84da1a7eeb
* Sun Dec 15 2024 Justin M. Forbes <jforbes@fedoraproject.org> [6.12.5-0] - New config item for 6.12.5 (Justin M. Forbes) - x86/cpu: Add Lunar Lake to list of CPUs with a broken MONITOR implementation (Mark Pearson) [2332094] - Add a bug to BugsFixed (Justin M. Forbes) - Turn off libbpf dynamic for perf on f40 (Justin M. Forbes) - Linux v6.12.5 Resolves: rhbz#2332094 Signed-off-by: Justin M. Forbes <jforbes@fedoraproject.org>
4438 lines
137 KiB
Diff
4438 lines
137 KiB
Diff
Makefile | 40 +
|
|
arch/arm/Kconfig | 4 +-
|
|
arch/arm64/Kconfig | 2 +-
|
|
.../boot/dts/qcom/x1e80100-asus-vivobook-s15.dts | 8 +
|
|
arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 41 +
|
|
arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts | 47 ++
|
|
.../rockchip/rk3588-friendlyelec-cm3588-nas.dts | 47 ++
|
|
arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi | 47 ++
|
|
.../boot/dts/rockchip/rk3588-orangepi-5-plus.dts | 47 ++
|
|
arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 47 ++
|
|
arch/arm64/boot/dts/rockchip/rk3588s-odroid-m2.dts | 47 ++
|
|
.../arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts | 47 ++
|
|
arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 57 ++
|
|
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 +-
|
|
drivers/acpi/apei/hest.c | 8 +
|
|
drivers/acpi/irq.c | 17 +-
|
|
drivers/acpi/scan.c | 9 +
|
|
drivers/ata/libahci.c | 18 +
|
|
drivers/bluetooth/btusb.c | 2 +
|
|
drivers/char/ipmi/ipmi_dmi.c | 15 +
|
|
drivers/char/ipmi/ipmi_msghandler.c | 16 +-
|
|
drivers/firmware/efi/Makefile | 1 +
|
|
drivers/firmware/efi/efi.c | 124 ++-
|
|
drivers/firmware/efi/secureboot.c | 38 +
|
|
drivers/gpu/drm/bridge/synopsys/Kconfig | 8 +
|
|
drivers/gpu/drm/bridge/synopsys/Makefile | 2 +
|
|
drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 647 ++++++++++++++++
|
|
drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.h | 834 +++++++++++++++++++++
|
|
drivers/gpu/drm/rockchip/Kconfig | 9 +
|
|
drivers/gpu/drm/rockchip/Makefile | 1 +
|
|
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 125 ++-
|
|
drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 424 +++++++++++
|
|
drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 25 +
|
|
drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 1 +
|
|
drivers/hid/hid-rmi.c | 66 --
|
|
drivers/hwtracing/coresight/coresight-etm4x-core.c | 19 +
|
|
drivers/input/rmi4/rmi_driver.c | 124 +--
|
|
drivers/iommu/iommu.c | 22 +
|
|
drivers/net/wireless/realtek/rtl8xxxu/core.c | 20 +
|
|
drivers/pci/quirks.c | 24 +
|
|
drivers/scsi/sd.c | 10 +
|
|
drivers/usb/core/hub.c | 7 +
|
|
include/drm/bridge/dw_hdmi_qp.h | 32 +
|
|
include/linux/efi.h | 22 +-
|
|
include/linux/lsm_hook_defs.h | 2 +
|
|
include/linux/rmi.h | 1 +
|
|
include/linux/security.h | 5 +
|
|
kernel/module/signing.c | 9 +-
|
|
scripts/tags.sh | 2 +
|
|
security/integrity/platform_certs/load_uefi.c | 6 +-
|
|
security/lockdown/Kconfig | 13 +
|
|
security/lockdown/lockdown.c | 1 +
|
|
security/security.c | 12 +
|
|
tools/tracing/rtla/src/utils.c | 32 +-
|
|
57 files changed, 3004 insertions(+), 262 deletions(-)
|
|
|
|
diff --git a/Makefile b/Makefile
|
|
index f158bfe6407ac..aaea72413c7d1 100644
|
|
--- a/Makefile
|
|
+++ b/Makefile
|
|
@@ -22,6 +22,18 @@ $(if $(filter __%, $(MAKECMDGOALS)), \
|
|
PHONY := __all
|
|
__all:
|
|
|
|
+# Set RHEL variables
|
|
+# Note that this ifdef'ery is required to handle when building with
|
|
+# the O= mechanism (relocate the object file results) due to upstream
|
|
+# commit 67d7c302 which broke our RHEL include file
|
|
+ifneq ($(realpath source),)
|
|
+include $(realpath source)/Makefile.rhelver
|
|
+else
|
|
+ifneq ($(realpath Makefile.rhelver),)
|
|
+include Makefile.rhelver
|
|
+endif
|
|
+endif
|
|
+
|
|
# We are using a recursive build, so we need to do a little thinking
|
|
# to get the ordering right.
|
|
#
|
|
@@ -333,6 +345,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).
|
|
@@ -1860,6 +1883,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
|
|
+
|
|
$(MODORDER): $(build-dir)
|
|
@:
|
|
|
|
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
|
|
index 202397be76d80..3d4ba33d4305f 100644
|
|
--- a/arch/arm/Kconfig
|
|
+++ b/arch/arm/Kconfig
|
|
@@ -1228,9 +1228,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
|
|
- 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 a11a7a42edbfb..86ed0ce54f26f 100644
|
|
--- a/arch/arm64/Kconfig
|
|
+++ b/arch/arm64/Kconfig
|
|
@@ -1394,7 +1394,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/qcom/x1e80100-asus-vivobook-s15.dts b/arch/arm64/boot/dts/qcom/x1e80100-asus-vivobook-s15.dts
|
|
index 2926a1aba7687..32f76df73dfa6 100644
|
|
--- a/arch/arm64/boot/dts/qcom/x1e80100-asus-vivobook-s15.dts
|
|
+++ b/arch/arm64/boot/dts/qcom/x1e80100-asus-vivobook-s15.dts
|
|
@@ -328,6 +328,14 @@ vreg_l3j_0p8: ldo3 {
|
|
};
|
|
};
|
|
|
|
+&gpu {
|
|
+ status = "okay";
|
|
+
|
|
+ zap-shader {
|
|
+ firmware-name = "qcom/x1e80100/ASUSTeK/vivobook-s15/qcdxkmsuc8380.mbn";
|
|
+ };
|
|
+};
|
|
+
|
|
&i2c0 {
|
|
clock-frequency = <400000>;
|
|
status = "okay";
|
|
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
|
|
index fc67585b64b7b..a337f3fb8377e 100644
|
|
--- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
|
|
+++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
|
|
@@ -1370,6 +1370,47 @@ i2s9_8ch: i2s@fddfc000 {
|
|
status = "disabled";
|
|
};
|
|
|
|
+ hdmi0: hdmi@fde80000 {
|
|
+ compatible = "rockchip,rk3588-dw-hdmi-qp";
|
|
+ reg = <0x0 0xfde80000 0x0 0x20000>;
|
|
+ clocks = <&cru PCLK_HDMITX0>,
|
|
+ <&cru CLK_HDMITX0_EARC>,
|
|
+ <&cru CLK_HDMITX0_REF>,
|
|
+ <&cru MCLK_I2S5_8CH_TX>,
|
|
+ <&cru CLK_HDMIHDP0>,
|
|
+ <&cru HCLK_VO1>;
|
|
+ clock-names = "pclk", "earc", "ref", "aud", "hdp", "hclk_vo1";
|
|
+ interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH 0>,
|
|
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH 0>,
|
|
+ <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH 0>,
|
|
+ <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH 0>,
|
|
+ <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH 0>;
|
|
+ interrupt-names = "avp", "cec", "earc", "main", "hpd";
|
|
+ phys = <&hdptxphy_hdmi0>;
|
|
+ pinctrl-names = "default";
|
|
+ pinctrl-0 = <&hdmim0_tx0_cec &hdmim0_tx0_hpd
|
|
+ &hdmim0_tx0_scl &hdmim0_tx0_sda>;
|
|
+ power-domains = <&power RK3588_PD_VO1>;
|
|
+ resets = <&cru SRST_HDMITX0_REF>, <&cru SRST_HDMIHDP0>;
|
|
+ reset-names = "ref", "hdp";
|
|
+ rockchip,grf = <&sys_grf>;
|
|
+ rockchip,vo-grf = <&vo1_grf>;
|
|
+ status = "disabled";
|
|
+
|
|
+ ports {
|
|
+ #address-cells = <1>;
|
|
+ #size-cells = <0>;
|
|
+
|
|
+ hdmi0_in: port@0 {
|
|
+ reg = <0>;
|
|
+ };
|
|
+
|
|
+ hdmi0_out: port@1 {
|
|
+ reg = <1>;
|
|
+ };
|
|
+ };
|
|
+ };
|
|
+
|
|
qos_gpu_m0: qos@fdf35000 {
|
|
compatible = "rockchip,rk3588-qos", "syscon";
|
|
reg = <0x0 0xfdf35000 0x0 0x20>;
|
|
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
|
|
index 00f660d50127f..7cf51a55863c0 100644
|
|
--- a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
|
|
+++ b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
|
|
@@ -9,6 +9,7 @@
|
|
#include <dt-bindings/gpio/gpio.h>
|
|
#include <dt-bindings/input/input.h>
|
|
#include <dt-bindings/pinctrl/rockchip.h>
|
|
+#include <dt-bindings/soc/rockchip,vop2.h>
|
|
#include <dt-bindings/usb/pd.h>
|
|
#include "rk3588.dtsi"
|
|
|
|
@@ -120,6 +121,17 @@ backlight: backlight {
|
|
pwms = <&pwm2 0 25000 0>;
|
|
};
|
|
|
|
+ hdmi0-con {
|
|
+ compatible = "hdmi-connector";
|
|
+ type = "a";
|
|
+
|
|
+ port {
|
|
+ hdmi0_con_in: endpoint {
|
|
+ remote-endpoint = <&hdmi0_out_con>;
|
|
+ };
|
|
+ };
|
|
+ };
|
|
+
|
|
pcie20_avdd0v85: pcie20-avdd0v85-regulator {
|
|
compatible = "regulator-fixed";
|
|
regulator-name = "pcie20_avdd0v85";
|
|
@@ -300,6 +312,26 @@ &gpu {
|
|
status = "okay";
|
|
};
|
|
|
|
+&hdmi0 {
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&hdmi0_in {
|
|
+ hdmi0_in_vp0: endpoint {
|
|
+ remote-endpoint = <&vp0_out_hdmi0>;
|
|
+ };
|
|
+};
|
|
+
|
|
+&hdmi0_out {
|
|
+ hdmi0_out_con: endpoint {
|
|
+ remote-endpoint = <&hdmi0_con_in>;
|
|
+ };
|
|
+};
|
|
+
|
|
+&hdptxphy_hdmi0 {
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
&i2c2 {
|
|
status = "okay";
|
|
|
|
@@ -1256,3 +1288,18 @@ &usb_host1_xhci {
|
|
dr_mode = "host";
|
|
status = "okay";
|
|
};
|
|
+
|
|
+&vop_mmu {
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&vop {
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&vp0 {
|
|
+ vp0_out_hdmi0: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
|
|
+ reg = <ROCKCHIP_VOP2_EP_HDMI0>;
|
|
+ remote-endpoint = <&hdmi0_in_vp0>;
|
|
+ };
|
|
+};
|
|
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588-nas.dts b/arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588-nas.dts
|
|
index 83103e4c7216f..dcc2c872b6c28 100644
|
|
--- a/arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588-nas.dts
|
|
+++ b/arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588-nas.dts
|
|
@@ -11,6 +11,7 @@
|
|
#include <dt-bindings/gpio/gpio.h>
|
|
#include <dt-bindings/input/input.h>
|
|
#include <dt-bindings/pinctrl/rockchip.h>
|
|
+#include <dt-bindings/soc/rockchip,vop2.h>
|
|
#include <dt-bindings/usb/pd.h>
|
|
#include "rk3588-friendlyelec-cm3588.dtsi"
|
|
|
|
@@ -89,6 +90,17 @@ button-user {
|
|
};
|
|
};
|
|
|
|
+ hdmi0-con {
|
|
+ compatible = "hdmi-connector";
|
|
+ type = "a";
|
|
+
|
|
+ port {
|
|
+ hdmi0_con_in: endpoint {
|
|
+ remote-endpoint = <&hdmi0_out_con>;
|
|
+ };
|
|
+ };
|
|
+ };
|
|
+
|
|
ir-receiver {
|
|
compatible = "gpio-ir-receiver";
|
|
gpios = <&gpio0 RK_PD4 GPIO_ACTIVE_LOW>;
|
|
@@ -307,6 +319,26 @@ &gpio4 {
|
|
"", "", "", "";
|
|
};
|
|
|
|
+&hdmi0 {
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&hdmi0_in {
|
|
+ hdmi0_in_vp0: endpoint {
|
|
+ remote-endpoint = <&vp0_out_hdmi0>;
|
|
+ };
|
|
+};
|
|
+
|
|
+&hdmi0_out {
|
|
+ hdmi0_out_con: endpoint {
|
|
+ remote-endpoint = <&hdmi0_con_in>;
|
|
+ };
|
|
+};
|
|
+
|
|
+&hdptxphy_hdmi0 {
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
/* Connected to MIPI-DSI0 */
|
|
&i2c5 {
|
|
pinctrl-names = "default";
|
|
@@ -776,3 +808,18 @@ usbdp_phy0_dp_altmode_mux: endpoint@1 {
|
|
&usbdp_phy1 {
|
|
status = "okay";
|
|
};
|
|
+
|
|
+&vop {
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&vop_mmu {
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&vp0 {
|
|
+ vp0_out_hdmi0: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
|
|
+ reg = <ROCKCHIP_VOP2_EP_HDMI0>;
|
|
+ remote-endpoint = <&hdmi0_in_vp0>;
|
|
+ };
|
|
+};
|
|
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
|
|
index fc131789b4c32..35d5d9f0c477f 100644
|
|
--- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
|
|
+++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
|
|
@@ -10,6 +10,7 @@
|
|
#include <dt-bindings/gpio/gpio.h>
|
|
#include <dt-bindings/input/input.h>
|
|
#include <dt-bindings/pinctrl/rockchip.h>
|
|
+#include <dt-bindings/soc/rockchip,vop2.h>
|
|
#include <dt-bindings/usb/pd.h>
|
|
#include "rk3588.dtsi"
|
|
|
|
@@ -40,6 +41,17 @@ chosen {
|
|
stdout-path = "serial2:1500000n8";
|
|
};
|
|
|
|
+ hdmi0-con {
|
|
+ compatible = "hdmi-connector";
|
|
+ type = "a";
|
|
+
|
|
+ port {
|
|
+ hdmi0_con_in: endpoint {
|
|
+ remote-endpoint = <&hdmi0_out_con>;
|
|
+ };
|
|
+ };
|
|
+ };
|
|
+
|
|
ir-receiver {
|
|
compatible = "gpio-ir-receiver";
|
|
gpios = <&gpio0 RK_PD4 GPIO_ACTIVE_LOW>;
|
|
@@ -318,6 +330,26 @@ &gpu {
|
|
status = "okay";
|
|
};
|
|
|
|
+&hdmi0 {
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&hdmi0_in {
|
|
+ hdmi0_in_vp0: endpoint {
|
|
+ remote-endpoint = <&vp0_out_hdmi0>;
|
|
+ };
|
|
+};
|
|
+
|
|
+&hdmi0_out {
|
|
+ hdmi0_out_con: endpoint {
|
|
+ remote-endpoint = <&hdmi0_con_in>;
|
|
+ };
|
|
+};
|
|
+
|
|
+&hdptxphy_hdmi0 {
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
&i2c0 {
|
|
pinctrl-names = "default";
|
|
pinctrl-0 = <&i2c0m2_xfer>;
|
|
@@ -1039,3 +1071,18 @@ &usb_host1_ehci {
|
|
&usb_host1_ohci {
|
|
status = "okay";
|
|
};
|
|
+
|
|
+&vop_mmu {
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&vop {
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&vp0 {
|
|
+ vp0_out_hdmi0: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
|
|
+ reg = <ROCKCHIP_VOP2_EP_HDMI0>;
|
|
+ remote-endpoint = <&hdmi0_in_vp0>;
|
|
+ };
|
|
+};
|
|
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts b/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
|
|
index dd4c79bcad87f..f6202321b5c09 100644
|
|
--- a/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
|
|
+++ b/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
|
|
@@ -9,6 +9,7 @@
|
|
#include <dt-bindings/leds/common.h>
|
|
#include <dt-bindings/input/input.h>
|
|
#include <dt-bindings/pinctrl/rockchip.h>
|
|
+#include <dt-bindings/soc/rockchip,vop2.h>
|
|
#include <dt-bindings/usb/pd.h>
|
|
#include "rk3588.dtsi"
|
|
|
|
@@ -85,6 +86,17 @@ led {
|
|
};
|
|
};
|
|
|
|
+ hdmi0-con {
|
|
+ compatible = "hdmi-connector";
|
|
+ type = "a";
|
|
+
|
|
+ port {
|
|
+ hdmi0_con_in: endpoint {
|
|
+ remote-endpoint = <&hdmi0_out_con>;
|
|
+ };
|
|
+ };
|
|
+ };
|
|
+
|
|
fan: pwm-fan {
|
|
compatible = "pwm-fan";
|
|
cooling-levels = <0 70 75 80 100>;
|
|
@@ -263,6 +275,26 @@ &cpu_l3 {
|
|
cpu-supply = <&vdd_cpu_lit_s0>;
|
|
};
|
|
|
|
+&hdmi0 {
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&hdmi0_in {
|
|
+ hdmi0_in_vp0: endpoint {
|
|
+ remote-endpoint = <&vp0_out_hdmi0>;
|
|
+ };
|
|
+};
|
|
+
|
|
+&hdmi0_out {
|
|
+ hdmi0_out_con: endpoint {
|
|
+ remote-endpoint = <&hdmi0_con_in>;
|
|
+ };
|
|
+};
|
|
+
|
|
+&hdptxphy_hdmi0 {
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
&i2c0 {
|
|
pinctrl-names = "default";
|
|
pinctrl-0 = <&i2c0m2_xfer>;
|
|
@@ -852,3 +884,18 @@ &usb_host1_ehci {
|
|
&usb_host1_ohci {
|
|
status = "okay";
|
|
};
|
|
+
|
|
+&vop_mmu {
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&vop {
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&vp0 {
|
|
+ vp0_out_hdmi0: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
|
|
+ reg = <ROCKCHIP_VOP2_EP_HDMI0>;
|
|
+ remote-endpoint = <&hdmi0_in_vp0>;
|
|
+ };
|
|
+};
|
|
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
|
|
index 6bd06e46a101d..7cbd7a5e1aa16 100644
|
|
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
|
|
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
|
|
@@ -4,6 +4,7 @@
|
|
|
|
#include <dt-bindings/gpio/gpio.h>
|
|
#include <dt-bindings/leds/common.h>
|
|
+#include <dt-bindings/soc/rockchip,vop2.h>
|
|
#include "rk3588.dtsi"
|
|
|
|
/ {
|
|
@@ -37,6 +38,17 @@ analog-sound {
|
|
pinctrl-0 = <&hp_detect>;
|
|
};
|
|
|
|
+ hdmi0-con {
|
|
+ compatible = "hdmi-connector";
|
|
+ type = "a";
|
|
+
|
|
+ port {
|
|
+ hdmi0_con_in: endpoint {
|
|
+ remote-endpoint = <&hdmi0_out_con>;
|
|
+ };
|
|
+ };
|
|
+ };
|
|
+
|
|
leds {
|
|
compatible = "gpio-leds";
|
|
pinctrl-names = "default";
|
|
@@ -192,6 +204,26 @@ &gpu {
|
|
status = "okay";
|
|
};
|
|
|
|
+&hdmi0 {
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&hdmi0_in {
|
|
+ hdmi0_in_vp0: endpoint {
|
|
+ remote-endpoint = <&vp0_out_hdmi0>;
|
|
+ };
|
|
+};
|
|
+
|
|
+&hdmi0_out {
|
|
+ hdmi0_out_con: endpoint {
|
|
+ remote-endpoint = <&hdmi0_con_in>;
|
|
+ };
|
|
+};
|
|
+
|
|
+&hdptxphy_hdmi0 {
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
&i2c0 {
|
|
pinctrl-names = "default";
|
|
pinctrl-0 = <&i2c0m2_xfer>;
|
|
@@ -858,3 +890,18 @@ &usb_host1_xhci {
|
|
&usb_host2_xhci {
|
|
status = "okay";
|
|
};
|
|
+
|
|
+&vop_mmu {
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&vop {
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&vp0 {
|
|
+ vp0_out_hdmi0: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
|
|
+ reg = <ROCKCHIP_VOP2_EP_HDMI0>;
|
|
+ remote-endpoint = <&hdmi0_in_vp0>;
|
|
+ };
|
|
+};
|
|
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-odroid-m2.dts b/arch/arm64/boot/dts/rockchip/rk3588s-odroid-m2.dts
|
|
index 63d91236ba9ff..8f034c6d494c4 100644
|
|
--- a/arch/arm64/boot/dts/rockchip/rk3588s-odroid-m2.dts
|
|
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-odroid-m2.dts
|
|
@@ -5,6 +5,7 @@
|
|
#include <dt-bindings/gpio/gpio.h>
|
|
#include <dt-bindings/leds/common.h>
|
|
#include <dt-bindings/pinctrl/rockchip.h>
|
|
+#include <dt-bindings/soc/rockchip,vop2.h>
|
|
#include <dt-bindings/usb/pd.h>
|
|
#include "rk3588s.dtsi"
|
|
|
|
@@ -22,6 +23,17 @@ chosen {
|
|
stdout-path = "serial2:1500000n8";
|
|
};
|
|
|
|
+ hdmi-con {
|
|
+ compatible = "hdmi-connector";
|
|
+ type = "a";
|
|
+
|
|
+ port {
|
|
+ hdmi_con_in: endpoint {
|
|
+ remote-endpoint = <&hdmi0_out_con>;
|
|
+ };
|
|
+ };
|
|
+ };
|
|
+
|
|
leds {
|
|
compatible = "gpio-leds";
|
|
pinctrl-names = "default";
|
|
@@ -236,6 +248,26 @@ &gpu {
|
|
status = "okay";
|
|
};
|
|
|
|
+&hdmi0 {
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&hdmi0_in {
|
|
+ hdmi0_in_vp0: endpoint {
|
|
+ remote-endpoint = <&vp0_out_hdmi0>;
|
|
+ };
|
|
+};
|
|
+
|
|
+&hdmi0_out {
|
|
+ hdmi0_out_con: endpoint {
|
|
+ remote-endpoint = <&hdmi_con_in>;
|
|
+ };
|
|
+};
|
|
+
|
|
+&hdptxphy_hdmi0 {
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
&i2c0 {
|
|
pinctrl-names = "default";
|
|
pinctrl-0 = <&i2c0m2_xfer>;
|
|
@@ -901,3 +933,18 @@ usbdp_phy0_dp_altmode_mux: endpoint@1 {
|
|
};
|
|
};
|
|
};
|
|
+
|
|
+&vop {
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&vop_mmu {
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&vp0 {
|
|
+ vp0_out_hdmi0: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
|
|
+ reg = <ROCKCHIP_VOP2_EP_HDMI0>;
|
|
+ remote-endpoint = <&hdmi0_in_vp0>;
|
|
+ };
|
|
+};
|
|
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts b/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts
|
|
index 6b77be6432495..7052641144e19 100644
|
|
--- a/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts
|
|
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts
|
|
@@ -6,6 +6,7 @@
|
|
#include <dt-bindings/leds/common.h>
|
|
#include <dt-bindings/input/input.h>
|
|
#include <dt-bindings/pinctrl/rockchip.h>
|
|
+#include <dt-bindings/soc/rockchip,vop2.h>
|
|
#include <dt-bindings/usb/pd.h>
|
|
#include "rk3588s.dtsi"
|
|
|
|
@@ -36,6 +37,17 @@ button-recovery {
|
|
};
|
|
};
|
|
|
|
+ hdmi0-con {
|
|
+ compatible = "hdmi-connector";
|
|
+ type = "a";
|
|
+
|
|
+ port {
|
|
+ hdmi0_con_in: endpoint {
|
|
+ remote-endpoint = <&hdmi0_out_con>;
|
|
+ };
|
|
+ };
|
|
+ };
|
|
+
|
|
leds {
|
|
compatible = "gpio-leds";
|
|
pinctrl-names = "default";
|
|
@@ -151,6 +163,26 @@ &gpu {
|
|
status = "okay";
|
|
};
|
|
|
|
+&hdmi0 {
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&hdmi0_in {
|
|
+ hdmi0_in_vp0: endpoint {
|
|
+ remote-endpoint = <&vp0_out_hdmi0>;
|
|
+ };
|
|
+};
|
|
+
|
|
+&hdmi0_out {
|
|
+ hdmi0_out_con: endpoint {
|
|
+ remote-endpoint = <&hdmi0_con_in>;
|
|
+ };
|
|
+};
|
|
+
|
|
+&hdptxphy_hdmi0 {
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
&i2c0 {
|
|
pinctrl-names = "default";
|
|
pinctrl-0 = <&i2c0m2_xfer>;
|
|
@@ -763,3 +795,18 @@ &usb_host1_ohci {
|
|
&usb_host2_xhci {
|
|
status = "okay";
|
|
};
|
|
+
|
|
+&vop_mmu {
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&vop {
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&vp0 {
|
|
+ vp0_out_hdmi0: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
|
|
+ reg = <ROCKCHIP_VOP2_EP_HDMI0>;
|
|
+ remote-endpoint = <&hdmi0_in_vp0>;
|
|
+ };
|
|
+};
|
|
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
|
|
index 294b99dd50da2..41e64a44e964b 100644
|
|
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
|
|
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
|
|
@@ -5,6 +5,7 @@
|
|
#include <dt-bindings/gpio/gpio.h>
|
|
#include <dt-bindings/leds/common.h>
|
|
#include <dt-bindings/pinctrl/rockchip.h>
|
|
+#include <dt-bindings/soc/rockchip,vop2.h>
|
|
#include "rk3588s.dtsi"
|
|
|
|
/ {
|
|
@@ -35,6 +36,17 @@ chosen {
|
|
stdout-path = "serial2:1500000n8";
|
|
};
|
|
|
|
+ hdmi0-con {
|
|
+ compatible = "hdmi-connector";
|
|
+ type = "d";
|
|
+
|
|
+ port {
|
|
+ hdmi0_con_in: endpoint {
|
|
+ remote-endpoint = <&hdmi0_out_con>;
|
|
+ };
|
|
+ };
|
|
+ };
|
|
+
|
|
leds {
|
|
compatible = "gpio-leds";
|
|
pinctrl-names = "default";
|
|
@@ -166,6 +178,11 @@ &cpu_l3 {
|
|
cpu-supply = <&vdd_cpu_lit_s0>;
|
|
};
|
|
|
|
+&gpu {
|
|
+ mali-supply = <&vdd_gpu_s0>;
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
&i2c0 {
|
|
pinctrl-names = "default";
|
|
pinctrl-0 = <&i2c0m2_xfer>;
|
|
@@ -296,6 +313,31 @@ &gmac1_rgmii_clk
|
|
status = "okay";
|
|
};
|
|
|
|
+&hdmi0 {
|
|
+ pinctrl-names = "default";
|
|
+ pinctrl-0 = <&hdmim0_tx0_cec
|
|
+ &hdmim1_tx0_hpd
|
|
+ &hdmim0_tx0_scl
|
|
+ &hdmim0_tx0_sda>;
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&hdmi0_in {
|
|
+ hdmi0_in_vp0: endpoint {
|
|
+ remote-endpoint = <&vp0_out_hdmi0>;
|
|
+ };
|
|
+};
|
|
+
|
|
+&hdmi0_out {
|
|
+ hdmi0_out_con: endpoint {
|
|
+ remote-endpoint = <&hdmi0_con_in>;
|
|
+ };
|
|
+};
|
|
+
|
|
+&hdptxphy_hdmi0 {
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
&mdio1 {
|
|
rgmii_phy1: ethernet-phy@1 {
|
|
/* RTL8211F */
|
|
@@ -784,3 +826,18 @@ &usb_host1_ohci {
|
|
&usb_host2_xhci {
|
|
status = "okay";
|
|
};
|
|
+
|
|
+&vop_mmu {
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&vop {
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&vp0 {
|
|
+ vp0_out_hdmi0: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
|
|
+ reg = <ROCKCHIP_VOP2_EP_HDMI0>;
|
|
+ remote-endpoint = <&hdmi0_in_vp0>;
|
|
+ };
|
|
+};
|
|
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 f17bb7bf93924..66e530380ee30 100644
|
|
--- a/arch/s390/kernel/ipl.c
|
|
+++ b/arch/s390/kernel/ipl.c
|
|
@@ -2479,3 +2479,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 a3fea683b2270..a3162d93f437d 100644
|
|
--- a/arch/s390/kernel/setup.c
|
|
+++ b/arch/s390/kernel/setup.c
|
|
@@ -49,6 +49,7 @@
|
|
#include <linux/memory.h>
|
|
#include <linux/compat.h>
|
|
#include <linux/start_kernel.h>
|
|
+#include <linux/security.h>
|
|
#include <linux/hugetlb.h>
|
|
#include <linux/kmemleak.h>
|
|
|
|
@@ -910,6 +911,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 f1fea506e20f4..6af50d80f54aa 100644
|
|
--- a/arch/x86/kernel/setup.c
|
|
+++ b/arch/x86/kernel/setup.c
|
|
@@ -21,6 +21,7 @@
|
|
#include <linux/root_dev.h>
|
|
#include <linux/hugetlb.h>
|
|
#include <linux/tboot.h>
|
|
+#include <linux/security.h>
|
|
#include <linux/usb/xhci-dbgp.h>
|
|
#include <linux/static_call.h>
|
|
#include <linux/swiotlb.h>
|
|
@@ -904,6 +905,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();
|
|
|
|
@@ -1070,19 +1078,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/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 1687483ff319e..390b67f19181a 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 7ecc401fb97f9..52917b1771227 100644
|
|
--- a/drivers/acpi/scan.c
|
|
+++ b/drivers/acpi/scan.c
|
|
@@ -1802,6 +1802,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 fdfa7b2662180..f5f8ba457c93f 100644
|
|
--- a/drivers/ata/libahci.c
|
|
+++ b/drivers/ata/libahci.c
|
|
@@ -729,6 +729,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/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
|
|
index 11755cb1eb163..202d43563e0bc 100644
|
|
--- a/drivers/bluetooth/btusb.c
|
|
+++ b/drivers/bluetooth/btusb.c
|
|
@@ -295,6 +295,8 @@ static const struct usb_device_id quirks_table[] = {
|
|
BTUSB_WIDEBAND_SPEECH },
|
|
{ USB_DEVICE(0x13d3, 0x3501), .driver_info = BTUSB_QCA_ROME |
|
|
BTUSB_WIDEBAND_SPEECH },
|
|
+ { USB_DEVICE(0x0489, 0xe0fc), .driver_info = BTUSB_QCA_WCN6855 |
|
|
+ BTUSB_WIDEBAND_SPEECH },
|
|
|
|
/* QCA WCN6855 chipset */
|
|
{ USB_DEVICE(0x0cf3, 0xe600), .driver_info = BTUSB_QCA_WCN6855 |
|
|
diff --git a/drivers/char/ipmi/ipmi_dmi.c b/drivers/char/ipmi/ipmi_dmi.c
|
|
index bbf7029e224be..cf7faa970dd65 100644
|
|
--- a/drivers/char/ipmi/ipmi_dmi.c
|
|
+++ b/drivers/char/ipmi/ipmi_dmi.c
|
|
@@ -215,6 +215,21 @@ static int __init scan_for_dmi_ipmi(void)
|
|
{
|
|
const struct dmi_device *dev = NULL;
|
|
|
|
+#ifdef CONFIG_ARM64
|
|
+ /* RHEL-only
|
|
+ * If this is ARM-based HPE m400, return now, because that platform
|
|
+ * reports the host-side ipmi address as intel port-io space, which
|
|
+ * does not exist in the ARM architecture.
|
|
+ */
|
|
+ const char *dmistr = dmi_get_system_info(DMI_PRODUCT_NAME);
|
|
+
|
|
+ if (dmistr && (strcmp("ProLiant m400 Server", dmistr) == 0)) {
|
|
+ pr_debug("%s does not support host ipmi\n", dmistr);
|
|
+ return 0;
|
|
+ }
|
|
+ /* END RHEL-only */
|
|
+#endif
|
|
+
|
|
while ((dev = dmi_find_device(DMI_DEV_TYPE_IPMI, NULL, dev)))
|
|
dmi_decode_ipmi((const struct dmi_header *) dev->device_data);
|
|
|
|
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
|
|
index e12b531f5c2f3..082707f8dff8c 100644
|
|
--- a/drivers/char/ipmi/ipmi_msghandler.c
|
|
+++ b/drivers/char/ipmi/ipmi_msghandler.c
|
|
@@ -35,6 +35,7 @@
|
|
#include <linux/uuid.h>
|
|
#include <linux/nospec.h>
|
|
#include <linux/vmalloc.h>
|
|
+#include <linux/dmi.h>
|
|
#include <linux/delay.h>
|
|
|
|
#define IPMI_DRIVER_VERSION "39.2"
|
|
@@ -5510,8 +5511,21 @@ static int __init ipmi_init_msghandler_mod(void)
|
|
{
|
|
int rv;
|
|
|
|
- pr_info("version " IPMI_DRIVER_VERSION "\n");
|
|
+#ifdef CONFIG_ARM64
|
|
+ /* RHEL-only
|
|
+ * If this is ARM-based HPE m400, return now, because that platform
|
|
+ * reports the host-side ipmi address as intel port-io space, which
|
|
+ * does not exist in the ARM architecture.
|
|
+ */
|
|
+ const char *dmistr = dmi_get_system_info(DMI_PRODUCT_NAME);
|
|
|
|
+ if (dmistr && (strcmp("ProLiant m400 Server", dmistr) == 0)) {
|
|
+ pr_debug("%s does not support host ipmi\n", dmistr);
|
|
+ return -ENOSYS;
|
|
+ }
|
|
+ /* END RHEL-only */
|
|
+#endif
|
|
+ pr_info("version " IPMI_DRIVER_VERSION "\n");
|
|
mutex_lock(&ipmi_interfaces_mutex);
|
|
rv = ipmi_register_driver();
|
|
mutex_unlock(&ipmi_interfaces_mutex);
|
|
diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
|
|
index a2d0009560d0f..4f3486e6a84b2 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 70490bf2697b1..2973cce74abdf 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>
|
|
|
|
@@ -993,40 +994,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,
|
|
+ sizeof(struct efi_error_code), num,
|
|
+ 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,
|
|
+ sizeof(struct efi_error_code), num,
|
|
+ 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/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/bridge/synopsys/Kconfig b/drivers/gpu/drm/bridge/synopsys/Kconfig
|
|
index 15fc182d05ef0..ca416dab156d8 100644
|
|
--- a/drivers/gpu/drm/bridge/synopsys/Kconfig
|
|
+++ b/drivers/gpu/drm/bridge/synopsys/Kconfig
|
|
@@ -46,6 +46,14 @@ config DRM_DW_HDMI_CEC
|
|
Support the CE interface which is part of the Synopsys
|
|
Designware HDMI block.
|
|
|
|
+config DRM_DW_HDMI_QP
|
|
+ tristate
|
|
+ select DRM_DISPLAY_HDMI_HELPER
|
|
+ select DRM_DISPLAY_HDMI_STATE_HELPER
|
|
+ select DRM_DISPLAY_HELPER
|
|
+ select DRM_KMS_HELPER
|
|
+ select REGMAP_MMIO
|
|
+
|
|
config DRM_DW_MIPI_DSI
|
|
tristate
|
|
select DRM_KMS_HELPER
|
|
diff --git a/drivers/gpu/drm/bridge/synopsys/Makefile b/drivers/gpu/drm/bridge/synopsys/Makefile
|
|
index ce715562e9e52..9869d9651ed1f 100644
|
|
--- a/drivers/gpu/drm/bridge/synopsys/Makefile
|
|
+++ b/drivers/gpu/drm/bridge/synopsys/Makefile
|
|
@@ -5,4 +5,6 @@ obj-$(CONFIG_DRM_DW_HDMI_GP_AUDIO) += dw-hdmi-gp-audio.o
|
|
obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o
|
|
obj-$(CONFIG_DRM_DW_HDMI_CEC) += dw-hdmi-cec.o
|
|
|
|
+obj-$(CONFIG_DRM_DW_HDMI_QP) += dw-hdmi-qp.o
|
|
+
|
|
obj-$(CONFIG_DRM_DW_MIPI_DSI) += dw-mipi-dsi.o
|
|
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
|
|
new file mode 100644
|
|
index 0000000000000..181c5164b2319
|
|
--- /dev/null
|
|
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
|
|
@@ -0,0 +1,647 @@
|
|
+// SPDX-License-Identifier: GPL-2.0-or-later
|
|
+/*
|
|
+ * Copyright (c) 2021-2022 Rockchip Electronics Co., Ltd.
|
|
+ * Copyright (c) 2024 Collabora Ltd.
|
|
+ *
|
|
+ * Author: Algea Cao <algea.cao@rock-chips.com>
|
|
+ * Author: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
|
+ */
|
|
+#include <linux/completion.h>
|
|
+#include <linux/hdmi.h>
|
|
+#include <linux/i2c.h>
|
|
+#include <linux/irq.h>
|
|
+#include <linux/module.h>
|
|
+#include <linux/mutex.h>
|
|
+#include <linux/of.h>
|
|
+#include <linux/workqueue.h>
|
|
+
|
|
+#include <drm/bridge/dw_hdmi_qp.h>
|
|
+#include <drm/display/drm_hdmi_helper.h>
|
|
+#include <drm/display/drm_hdmi_state_helper.h>
|
|
+#include <drm/drm_atomic.h>
|
|
+#include <drm/drm_atomic_helper.h>
|
|
+#include <drm/drm_bridge.h>
|
|
+#include <drm/drm_connector.h>
|
|
+#include <drm/drm_edid.h>
|
|
+#include <drm/drm_modes.h>
|
|
+
|
|
+#include <sound/hdmi-codec.h>
|
|
+
|
|
+#include "dw-hdmi-qp.h"
|
|
+
|
|
+#define DDC_CI_ADDR 0x37
|
|
+#define DDC_SEGMENT_ADDR 0x30
|
|
+
|
|
+#define HDMI14_MAX_TMDSCLK 340000000
|
|
+
|
|
+#define SCRAMB_POLL_DELAY_MS 3000
|
|
+
|
|
+struct dw_hdmi_qp_i2c {
|
|
+ struct i2c_adapter adap;
|
|
+
|
|
+ struct mutex lock; /* used to serialize data transfers */
|
|
+ struct completion cmp;
|
|
+ u8 stat;
|
|
+
|
|
+ u8 slave_reg;
|
|
+ bool is_regaddr;
|
|
+ bool is_segment;
|
|
+};
|
|
+
|
|
+struct dw_hdmi_qp {
|
|
+ struct drm_bridge bridge;
|
|
+
|
|
+ struct device *dev;
|
|
+ struct dw_hdmi_qp_i2c *i2c;
|
|
+
|
|
+ struct {
|
|
+ const struct dw_hdmi_qp_phy_ops *ops;
|
|
+ void *data;
|
|
+ } phy;
|
|
+
|
|
+ struct regmap *regm;
|
|
+};
|
|
+
|
|
+static void dw_hdmi_qp_write(struct dw_hdmi_qp *hdmi, unsigned int val,
|
|
+ int offset)
|
|
+{
|
|
+ regmap_write(hdmi->regm, offset, val);
|
|
+}
|
|
+
|
|
+static unsigned int dw_hdmi_qp_read(struct dw_hdmi_qp *hdmi, int offset)
|
|
+{
|
|
+ unsigned int val = 0;
|
|
+
|
|
+ regmap_read(hdmi->regm, offset, &val);
|
|
+
|
|
+ return val;
|
|
+}
|
|
+
|
|
+static void dw_hdmi_qp_mod(struct dw_hdmi_qp *hdmi, unsigned int data,
|
|
+ unsigned int mask, unsigned int reg)
|
|
+{
|
|
+ regmap_update_bits(hdmi->regm, reg, mask, data);
|
|
+}
|
|
+
|
|
+static int dw_hdmi_qp_i2c_read(struct dw_hdmi_qp *hdmi,
|
|
+ unsigned char *buf, unsigned int length)
|
|
+{
|
|
+ struct dw_hdmi_qp_i2c *i2c = hdmi->i2c;
|
|
+ int stat;
|
|
+
|
|
+ if (!i2c->is_regaddr) {
|
|
+ dev_dbg(hdmi->dev, "set read register address to 0\n");
|
|
+ i2c->slave_reg = 0x00;
|
|
+ i2c->is_regaddr = true;
|
|
+ }
|
|
+
|
|
+ while (length--) {
|
|
+ reinit_completion(&i2c->cmp);
|
|
+
|
|
+ dw_hdmi_qp_mod(hdmi, i2c->slave_reg++ << 12, I2CM_ADDR,
|
|
+ I2CM_INTERFACE_CONTROL0);
|
|
+
|
|
+ if (i2c->is_segment)
|
|
+ dw_hdmi_qp_mod(hdmi, I2CM_EXT_READ, I2CM_WR_MASK,
|
|
+ I2CM_INTERFACE_CONTROL0);
|
|
+ else
|
|
+ dw_hdmi_qp_mod(hdmi, I2CM_FM_READ, I2CM_WR_MASK,
|
|
+ I2CM_INTERFACE_CONTROL0);
|
|
+
|
|
+ stat = wait_for_completion_timeout(&i2c->cmp, HZ / 10);
|
|
+ if (!stat) {
|
|
+ dev_err(hdmi->dev, "i2c read timed out\n");
|
|
+ dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0);
|
|
+ return -EAGAIN;
|
|
+ }
|
|
+
|
|
+ /* Check for error condition on the bus */
|
|
+ if (i2c->stat & I2CM_NACK_RCVD_IRQ) {
|
|
+ dev_err(hdmi->dev, "i2c read error\n");
|
|
+ dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0);
|
|
+ return -EIO;
|
|
+ }
|
|
+
|
|
+ *buf++ = dw_hdmi_qp_read(hdmi, I2CM_INTERFACE_RDDATA_0_3) & 0xff;
|
|
+ dw_hdmi_qp_mod(hdmi, 0, I2CM_WR_MASK, I2CM_INTERFACE_CONTROL0);
|
|
+ }
|
|
+
|
|
+ i2c->is_segment = false;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int dw_hdmi_qp_i2c_write(struct dw_hdmi_qp *hdmi,
|
|
+ unsigned char *buf, unsigned int length)
|
|
+{
|
|
+ struct dw_hdmi_qp_i2c *i2c = hdmi->i2c;
|
|
+ int stat;
|
|
+
|
|
+ if (!i2c->is_regaddr) {
|
|
+ /* Use the first write byte as register address */
|
|
+ i2c->slave_reg = buf[0];
|
|
+ length--;
|
|
+ buf++;
|
|
+ i2c->is_regaddr = true;
|
|
+ }
|
|
+
|
|
+ while (length--) {
|
|
+ reinit_completion(&i2c->cmp);
|
|
+
|
|
+ dw_hdmi_qp_write(hdmi, *buf++, I2CM_INTERFACE_WRDATA_0_3);
|
|
+ dw_hdmi_qp_mod(hdmi, i2c->slave_reg++ << 12, I2CM_ADDR,
|
|
+ I2CM_INTERFACE_CONTROL0);
|
|
+ dw_hdmi_qp_mod(hdmi, I2CM_FM_WRITE, I2CM_WR_MASK,
|
|
+ I2CM_INTERFACE_CONTROL0);
|
|
+
|
|
+ stat = wait_for_completion_timeout(&i2c->cmp, HZ / 10);
|
|
+ if (!stat) {
|
|
+ dev_err(hdmi->dev, "i2c write time out!\n");
|
|
+ dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0);
|
|
+ return -EAGAIN;
|
|
+ }
|
|
+
|
|
+ /* Check for error condition on the bus */
|
|
+ if (i2c->stat & I2CM_NACK_RCVD_IRQ) {
|
|
+ dev_err(hdmi->dev, "i2c write nack!\n");
|
|
+ dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0);
|
|
+ return -EIO;
|
|
+ }
|
|
+
|
|
+ dw_hdmi_qp_mod(hdmi, 0, I2CM_WR_MASK, I2CM_INTERFACE_CONTROL0);
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int dw_hdmi_qp_i2c_xfer(struct i2c_adapter *adap,
|
|
+ struct i2c_msg *msgs, int num)
|
|
+{
|
|
+ struct dw_hdmi_qp *hdmi = i2c_get_adapdata(adap);
|
|
+ struct dw_hdmi_qp_i2c *i2c = hdmi->i2c;
|
|
+ u8 addr = msgs[0].addr;
|
|
+ int i, ret = 0;
|
|
+
|
|
+ if (addr == DDC_CI_ADDR)
|
|
+ /*
|
|
+ * The internal I2C controller does not support the multi-byte
|
|
+ * read and write operations needed for DDC/CI.
|
|
+ * FIXME: Blacklist the DDC/CI address until we filter out
|
|
+ * unsupported I2C operations.
|
|
+ */
|
|
+ return -EOPNOTSUPP;
|
|
+
|
|
+ for (i = 0; i < num; i++) {
|
|
+ if (msgs[i].len == 0) {
|
|
+ dev_err(hdmi->dev,
|
|
+ "unsupported transfer %d/%d, no data\n",
|
|
+ i + 1, num);
|
|
+ return -EOPNOTSUPP;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ guard(mutex)(&i2c->lock);
|
|
+
|
|
+ /* Unmute DONE and ERROR interrupts */
|
|
+ dw_hdmi_qp_mod(hdmi, I2CM_NACK_RCVD_MASK_N | I2CM_OP_DONE_MASK_N,
|
|
+ I2CM_NACK_RCVD_MASK_N | I2CM_OP_DONE_MASK_N,
|
|
+ MAINUNIT_1_INT_MASK_N);
|
|
+
|
|
+ /* Set slave device address taken from the first I2C message */
|
|
+ if (addr == DDC_SEGMENT_ADDR && msgs[0].len == 1)
|
|
+ addr = DDC_ADDR;
|
|
+
|
|
+ dw_hdmi_qp_mod(hdmi, addr << 5, I2CM_SLVADDR, I2CM_INTERFACE_CONTROL0);
|
|
+
|
|
+ /* Set slave device register address on transfer */
|
|
+ i2c->is_regaddr = false;
|
|
+
|
|
+ /* Set segment pointer for I2C extended read mode operation */
|
|
+ i2c->is_segment = false;
|
|
+
|
|
+ for (i = 0; i < num; i++) {
|
|
+ if (msgs[i].addr == DDC_SEGMENT_ADDR && msgs[i].len == 1) {
|
|
+ i2c->is_segment = true;
|
|
+ dw_hdmi_qp_mod(hdmi, DDC_SEGMENT_ADDR, I2CM_SEG_ADDR,
|
|
+ I2CM_INTERFACE_CONTROL1);
|
|
+ dw_hdmi_qp_mod(hdmi, *msgs[i].buf << 7, I2CM_SEG_PTR,
|
|
+ I2CM_INTERFACE_CONTROL1);
|
|
+ } else {
|
|
+ if (msgs[i].flags & I2C_M_RD)
|
|
+ ret = dw_hdmi_qp_i2c_read(hdmi, msgs[i].buf,
|
|
+ msgs[i].len);
|
|
+ else
|
|
+ ret = dw_hdmi_qp_i2c_write(hdmi, msgs[i].buf,
|
|
+ msgs[i].len);
|
|
+ }
|
|
+ if (ret < 0)
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ if (!ret)
|
|
+ ret = num;
|
|
+
|
|
+ /* Mute DONE and ERROR interrupts */
|
|
+ dw_hdmi_qp_mod(hdmi, 0, I2CM_OP_DONE_MASK_N | I2CM_NACK_RCVD_MASK_N,
|
|
+ MAINUNIT_1_INT_MASK_N);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static u32 dw_hdmi_qp_i2c_func(struct i2c_adapter *adapter)
|
|
+{
|
|
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
|
|
+}
|
|
+
|
|
+static const struct i2c_algorithm dw_hdmi_qp_algorithm = {
|
|
+ .master_xfer = dw_hdmi_qp_i2c_xfer,
|
|
+ .functionality = dw_hdmi_qp_i2c_func,
|
|
+};
|
|
+
|
|
+static struct i2c_adapter *dw_hdmi_qp_i2c_adapter(struct dw_hdmi_qp *hdmi)
|
|
+{
|
|
+ struct dw_hdmi_qp_i2c *i2c;
|
|
+ struct i2c_adapter *adap;
|
|
+ int ret;
|
|
+
|
|
+ i2c = devm_kzalloc(hdmi->dev, sizeof(*i2c), GFP_KERNEL);
|
|
+ if (!i2c)
|
|
+ return ERR_PTR(-ENOMEM);
|
|
+
|
|
+ mutex_init(&i2c->lock);
|
|
+ init_completion(&i2c->cmp);
|
|
+
|
|
+ adap = &i2c->adap;
|
|
+ adap->owner = THIS_MODULE;
|
|
+ adap->dev.parent = hdmi->dev;
|
|
+ adap->algo = &dw_hdmi_qp_algorithm;
|
|
+ strscpy(adap->name, "DesignWare HDMI QP", sizeof(adap->name));
|
|
+
|
|
+ i2c_set_adapdata(adap, hdmi);
|
|
+
|
|
+ ret = devm_i2c_add_adapter(hdmi->dev, adap);
|
|
+ if (ret) {
|
|
+ dev_warn(hdmi->dev, "cannot add %s I2C adapter\n", adap->name);
|
|
+ devm_kfree(hdmi->dev, i2c);
|
|
+ return ERR_PTR(ret);
|
|
+ }
|
|
+
|
|
+ hdmi->i2c = i2c;
|
|
+ dev_info(hdmi->dev, "registered %s I2C bus driver\n", adap->name);
|
|
+
|
|
+ return adap;
|
|
+}
|
|
+
|
|
+static int dw_hdmi_qp_config_avi_infoframe(struct dw_hdmi_qp *hdmi,
|
|
+ const u8 *buffer, size_t len)
|
|
+{
|
|
+ u32 val, i, j;
|
|
+
|
|
+ if (len != HDMI_INFOFRAME_SIZE(AVI)) {
|
|
+ dev_err(hdmi->dev, "failed to configure avi infoframe\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * DW HDMI QP IP uses a different byte format from standard AVI info
|
|
+ * frames, though generally the bits are in the correct bytes.
|
|
+ */
|
|
+ val = buffer[1] << 8 | buffer[2] << 16;
|
|
+ dw_hdmi_qp_write(hdmi, val, PKT_AVI_CONTENTS0);
|
|
+
|
|
+ for (i = 0; i < 4; i++) {
|
|
+ for (j = 0; j < 4; j++) {
|
|
+ if (i * 4 + j >= 14)
|
|
+ break;
|
|
+ if (!j)
|
|
+ val = buffer[i * 4 + j + 3];
|
|
+ val |= buffer[i * 4 + j + 3] << (8 * j);
|
|
+ }
|
|
+
|
|
+ dw_hdmi_qp_write(hdmi, val, PKT_AVI_CONTENTS1 + i * 4);
|
|
+ }
|
|
+
|
|
+ dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_AVI_FIELDRATE, PKTSCHED_PKT_CONFIG1);
|
|
+
|
|
+ dw_hdmi_qp_mod(hdmi, PKTSCHED_AVI_TX_EN | PKTSCHED_GCP_TX_EN,
|
|
+ PKTSCHED_AVI_TX_EN | PKTSCHED_GCP_TX_EN, PKTSCHED_PKT_EN);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int dw_hdmi_qp_config_drm_infoframe(struct dw_hdmi_qp *hdmi,
|
|
+ const u8 *buffer, size_t len)
|
|
+{
|
|
+ u32 val, i;
|
|
+
|
|
+ if (len != HDMI_INFOFRAME_SIZE(DRM)) {
|
|
+ dev_err(hdmi->dev, "failed to configure drm infoframe\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_DRMI_TX_EN, PKTSCHED_PKT_EN);
|
|
+
|
|
+ val = buffer[1] << 8 | buffer[2] << 16;
|
|
+ dw_hdmi_qp_write(hdmi, val, PKT_DRMI_CONTENTS0);
|
|
+
|
|
+ for (i = 0; i <= buffer[2]; i++) {
|
|
+ if (i % 4 == 0)
|
|
+ val = buffer[3 + i];
|
|
+ val |= buffer[3 + i] << ((i % 4) * 8);
|
|
+
|
|
+ if ((i % 4 == 3) || i == buffer[2])
|
|
+ dw_hdmi_qp_write(hdmi, val,
|
|
+ PKT_DRMI_CONTENTS1 + ((i / 4) * 4));
|
|
+ }
|
|
+
|
|
+ dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_DRMI_FIELDRATE, PKTSCHED_PKT_CONFIG1);
|
|
+ dw_hdmi_qp_mod(hdmi, PKTSCHED_DRMI_TX_EN, PKTSCHED_DRMI_TX_EN,
|
|
+ PKTSCHED_PKT_EN);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int dw_hdmi_qp_bridge_atomic_check(struct drm_bridge *bridge,
|
|
+ struct drm_bridge_state *bridge_state,
|
|
+ struct drm_crtc_state *crtc_state,
|
|
+ struct drm_connector_state *conn_state)
|
|
+{
|
|
+ struct dw_hdmi_qp *hdmi = bridge->driver_private;
|
|
+ int ret;
|
|
+
|
|
+ ret = drm_atomic_helper_connector_hdmi_check(conn_state->connector,
|
|
+ conn_state->state);
|
|
+ if (ret)
|
|
+ dev_dbg(hdmi->dev, "%s failed: %d\n", __func__, ret);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static void dw_hdmi_qp_bridge_atomic_enable(struct drm_bridge *bridge,
|
|
+ struct drm_bridge_state *old_state)
|
|
+{
|
|
+ struct dw_hdmi_qp *hdmi = bridge->driver_private;
|
|
+ struct drm_atomic_state *state = old_state->base.state;
|
|
+ struct drm_connector_state *conn_state;
|
|
+ struct drm_connector *connector;
|
|
+ unsigned int op_mode;
|
|
+
|
|
+ connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);
|
|
+ if (WARN_ON(!connector))
|
|
+ return;
|
|
+
|
|
+ conn_state = drm_atomic_get_new_connector_state(state, connector);
|
|
+ if (WARN_ON(!conn_state))
|
|
+ return;
|
|
+
|
|
+ if (connector->display_info.is_hdmi) {
|
|
+ dev_dbg(hdmi->dev, "%s mode=HDMI rate=%llu\n",
|
|
+ __func__, conn_state->hdmi.tmds_char_rate);
|
|
+ op_mode = 0;
|
|
+ } else {
|
|
+ dev_dbg(hdmi->dev, "%s mode=DVI\n", __func__);
|
|
+ op_mode = OPMODE_DVI;
|
|
+ }
|
|
+
|
|
+ hdmi->phy.ops->init(hdmi, hdmi->phy.data);
|
|
+
|
|
+ dw_hdmi_qp_mod(hdmi, HDCP2_BYPASS, HDCP2_BYPASS, HDCP2LOGIC_CONFIG0);
|
|
+ dw_hdmi_qp_mod(hdmi, op_mode, OPMODE_DVI, LINK_CONFIG0);
|
|
+
|
|
+ drm_atomic_helper_connector_hdmi_update_infoframes(connector, state);
|
|
+}
|
|
+
|
|
+static void dw_hdmi_qp_bridge_atomic_disable(struct drm_bridge *bridge,
|
|
+ struct drm_bridge_state *old_state)
|
|
+{
|
|
+ struct dw_hdmi_qp *hdmi = bridge->driver_private;
|
|
+
|
|
+ hdmi->phy.ops->disable(hdmi, hdmi->phy.data);
|
|
+}
|
|
+
|
|
+static enum drm_connector_status
|
|
+dw_hdmi_qp_bridge_detect(struct drm_bridge *bridge)
|
|
+{
|
|
+ struct dw_hdmi_qp *hdmi = bridge->driver_private;
|
|
+
|
|
+ return hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data);
|
|
+}
|
|
+
|
|
+static const struct drm_edid *
|
|
+dw_hdmi_qp_bridge_edid_read(struct drm_bridge *bridge,
|
|
+ struct drm_connector *connector)
|
|
+{
|
|
+ struct dw_hdmi_qp *hdmi = bridge->driver_private;
|
|
+ const struct drm_edid *drm_edid;
|
|
+
|
|
+ drm_edid = drm_edid_read_ddc(connector, bridge->ddc);
|
|
+ if (!drm_edid)
|
|
+ dev_dbg(hdmi->dev, "failed to get edid\n");
|
|
+
|
|
+ return drm_edid;
|
|
+}
|
|
+
|
|
+static enum drm_mode_status
|
|
+dw_hdmi_qp_bridge_mode_valid(struct drm_bridge *bridge,
|
|
+ const struct drm_display_info *info,
|
|
+ const struct drm_display_mode *mode)
|
|
+{
|
|
+ struct dw_hdmi_qp *hdmi = bridge->driver_private;
|
|
+ unsigned long long rate;
|
|
+
|
|
+ rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB);
|
|
+ if (rate > HDMI14_MAX_TMDSCLK) {
|
|
+ dev_dbg(hdmi->dev, "Unsupported mode clock: %d\n", mode->clock);
|
|
+ return MODE_CLOCK_HIGH;
|
|
+ }
|
|
+
|
|
+ return MODE_OK;
|
|
+}
|
|
+
|
|
+static int dw_hdmi_qp_bridge_clear_infoframe(struct drm_bridge *bridge,
|
|
+ enum hdmi_infoframe_type type)
|
|
+{
|
|
+ struct dw_hdmi_qp *hdmi = bridge->driver_private;
|
|
+
|
|
+ switch (type) {
|
|
+ case HDMI_INFOFRAME_TYPE_AVI:
|
|
+ dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_AVI_TX_EN | PKTSCHED_GCP_TX_EN,
|
|
+ PKTSCHED_PKT_EN);
|
|
+ break;
|
|
+
|
|
+ case HDMI_INFOFRAME_TYPE_DRM:
|
|
+ dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_DRMI_TX_EN, PKTSCHED_PKT_EN);
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+ dev_dbg(hdmi->dev, "Unsupported infoframe type %x\n", type);
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int dw_hdmi_qp_bridge_write_infoframe(struct drm_bridge *bridge,
|
|
+ enum hdmi_infoframe_type type,
|
|
+ const u8 *buffer, size_t len)
|
|
+{
|
|
+ struct dw_hdmi_qp *hdmi = bridge->driver_private;
|
|
+
|
|
+ dw_hdmi_qp_bridge_clear_infoframe(bridge, type);
|
|
+
|
|
+ switch (type) {
|
|
+ case HDMI_INFOFRAME_TYPE_AVI:
|
|
+ return dw_hdmi_qp_config_avi_infoframe(hdmi, buffer, len);
|
|
+
|
|
+ case HDMI_INFOFRAME_TYPE_DRM:
|
|
+ return dw_hdmi_qp_config_drm_infoframe(hdmi, buffer, len);
|
|
+
|
|
+ default:
|
|
+ dev_dbg(hdmi->dev, "Unsupported infoframe type %x\n", type);
|
|
+ return 0;
|
|
+ }
|
|
+}
|
|
+
|
|
+static const struct drm_bridge_funcs dw_hdmi_qp_bridge_funcs = {
|
|
+ .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
|
|
+ .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
|
|
+ .atomic_reset = drm_atomic_helper_bridge_reset,
|
|
+ .atomic_check = dw_hdmi_qp_bridge_atomic_check,
|
|
+ .atomic_enable = dw_hdmi_qp_bridge_atomic_enable,
|
|
+ .atomic_disable = dw_hdmi_qp_bridge_atomic_disable,
|
|
+ .detect = dw_hdmi_qp_bridge_detect,
|
|
+ .edid_read = dw_hdmi_qp_bridge_edid_read,
|
|
+ .mode_valid = dw_hdmi_qp_bridge_mode_valid,
|
|
+ .hdmi_clear_infoframe = dw_hdmi_qp_bridge_clear_infoframe,
|
|
+ .hdmi_write_infoframe = dw_hdmi_qp_bridge_write_infoframe,
|
|
+};
|
|
+
|
|
+static irqreturn_t dw_hdmi_qp_main_hardirq(int irq, void *dev_id)
|
|
+{
|
|
+ struct dw_hdmi_qp *hdmi = dev_id;
|
|
+ struct dw_hdmi_qp_i2c *i2c = hdmi->i2c;
|
|
+ u32 stat;
|
|
+
|
|
+ stat = dw_hdmi_qp_read(hdmi, MAINUNIT_1_INT_STATUS);
|
|
+
|
|
+ i2c->stat = stat & (I2CM_OP_DONE_IRQ | I2CM_READ_REQUEST_IRQ |
|
|
+ I2CM_NACK_RCVD_IRQ);
|
|
+
|
|
+ if (i2c->stat) {
|
|
+ dw_hdmi_qp_write(hdmi, i2c->stat, MAINUNIT_1_INT_CLEAR);
|
|
+ complete(&i2c->cmp);
|
|
+ }
|
|
+
|
|
+ if (stat)
|
|
+ return IRQ_HANDLED;
|
|
+
|
|
+ return IRQ_NONE;
|
|
+}
|
|
+
|
|
+static const struct regmap_config dw_hdmi_qp_regmap_config = {
|
|
+ .reg_bits = 32,
|
|
+ .val_bits = 32,
|
|
+ .reg_stride = 4,
|
|
+ .max_register = EARCRX_1_INT_FORCE,
|
|
+};
|
|
+
|
|
+static void dw_hdmi_qp_init_hw(struct dw_hdmi_qp *hdmi)
|
|
+{
|
|
+ dw_hdmi_qp_write(hdmi, 0, MAINUNIT_0_INT_MASK_N);
|
|
+ dw_hdmi_qp_write(hdmi, 0, MAINUNIT_1_INT_MASK_N);
|
|
+ dw_hdmi_qp_write(hdmi, 428571429, TIMER_BASE_CONFIG0);
|
|
+
|
|
+ /* Software reset */
|
|
+ dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0);
|
|
+
|
|
+ dw_hdmi_qp_write(hdmi, 0x085c085c, I2CM_FM_SCL_CONFIG0);
|
|
+
|
|
+ dw_hdmi_qp_mod(hdmi, 0, I2CM_FM_EN, I2CM_INTERFACE_CONTROL0);
|
|
+
|
|
+ /* Clear DONE and ERROR interrupts */
|
|
+ dw_hdmi_qp_write(hdmi, I2CM_OP_DONE_CLEAR | I2CM_NACK_RCVD_CLEAR,
|
|
+ MAINUNIT_1_INT_CLEAR);
|
|
+
|
|
+ if (hdmi->phy.ops->setup_hpd)
|
|
+ hdmi->phy.ops->setup_hpd(hdmi, hdmi->phy.data);
|
|
+}
|
|
+
|
|
+struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev,
|
|
+ struct drm_encoder *encoder,
|
|
+ const struct dw_hdmi_qp_plat_data *plat_data)
|
|
+{
|
|
+ struct device *dev = &pdev->dev;
|
|
+ struct dw_hdmi_qp *hdmi;
|
|
+ void __iomem *regs;
|
|
+ int ret;
|
|
+
|
|
+ if (!plat_data->phy_ops || !plat_data->phy_ops->init ||
|
|
+ !plat_data->phy_ops->disable || !plat_data->phy_ops->read_hpd) {
|
|
+ dev_err(dev, "Missing platform PHY ops\n");
|
|
+ return ERR_PTR(-ENODEV);
|
|
+ }
|
|
+
|
|
+ hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
|
|
+ if (!hdmi)
|
|
+ return ERR_PTR(-ENOMEM);
|
|
+
|
|
+ hdmi->dev = dev;
|
|
+
|
|
+ regs = devm_platform_ioremap_resource(pdev, 0);
|
|
+ if (IS_ERR(regs))
|
|
+ return ERR_CAST(regs);
|
|
+
|
|
+ hdmi->regm = devm_regmap_init_mmio(dev, regs, &dw_hdmi_qp_regmap_config);
|
|
+ if (IS_ERR(hdmi->regm)) {
|
|
+ dev_err(dev, "Failed to configure regmap\n");
|
|
+ return ERR_CAST(hdmi->regm);
|
|
+ }
|
|
+
|
|
+ hdmi->phy.ops = plat_data->phy_ops;
|
|
+ hdmi->phy.data = plat_data->phy_data;
|
|
+
|
|
+ dw_hdmi_qp_init_hw(hdmi);
|
|
+
|
|
+ ret = devm_request_threaded_irq(dev, plat_data->main_irq,
|
|
+ dw_hdmi_qp_main_hardirq, NULL,
|
|
+ IRQF_SHARED, dev_name(dev), hdmi);
|
|
+ if (ret)
|
|
+ return ERR_PTR(ret);
|
|
+
|
|
+ hdmi->bridge.driver_private = hdmi;
|
|
+ hdmi->bridge.funcs = &dw_hdmi_qp_bridge_funcs;
|
|
+ hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT |
|
|
+ DRM_BRIDGE_OP_EDID |
|
|
+ DRM_BRIDGE_OP_HDMI |
|
|
+ DRM_BRIDGE_OP_HPD;
|
|
+ hdmi->bridge.of_node = pdev->dev.of_node;
|
|
+ hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
|
|
+ hdmi->bridge.vendor = "Synopsys";
|
|
+ hdmi->bridge.product = "DW HDMI QP TX";
|
|
+
|
|
+ hdmi->bridge.ddc = dw_hdmi_qp_i2c_adapter(hdmi);
|
|
+ if (IS_ERR(hdmi->bridge.ddc))
|
|
+ return ERR_CAST(hdmi->bridge.ddc);
|
|
+
|
|
+ ret = devm_drm_bridge_add(dev, &hdmi->bridge);
|
|
+ if (ret)
|
|
+ return ERR_PTR(ret);
|
|
+
|
|
+ ret = drm_bridge_attach(encoder, &hdmi->bridge, NULL,
|
|
+ DRM_BRIDGE_ATTACH_NO_CONNECTOR);
|
|
+ if (ret)
|
|
+ return ERR_PTR(ret);
|
|
+
|
|
+ return hdmi;
|
|
+}
|
|
+EXPORT_SYMBOL_GPL(dw_hdmi_qp_bind);
|
|
+
|
|
+void dw_hdmi_qp_resume(struct device *dev, struct dw_hdmi_qp *hdmi)
|
|
+{
|
|
+ dw_hdmi_qp_init_hw(hdmi);
|
|
+}
|
|
+EXPORT_SYMBOL_GPL(dw_hdmi_qp_resume);
|
|
+
|
|
+MODULE_AUTHOR("Algea Cao <algea.cao@rock-chips.com>");
|
|
+MODULE_AUTHOR("Cristian Ciocaltea <cristian.ciocaltea@collabora.com>");
|
|
+MODULE_DESCRIPTION("DW HDMI QP transmitter library");
|
|
+MODULE_LICENSE("GPL");
|
|
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.h
|
|
new file mode 100644
|
|
index 0000000000000..2115b8ef0bd68
|
|
--- /dev/null
|
|
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.h
|
|
@@ -0,0 +1,834 @@
|
|
+/* SPDX-License-Identifier: GPL-2.0 */
|
|
+/*
|
|
+ * Copyright (C) Rockchip Electronics Co.Ltd
|
|
+ * Author:
|
|
+ * Algea Cao <algea.cao@rock-chips.com>
|
|
+ */
|
|
+#ifndef __DW_HDMI_QP_H__
|
|
+#define __DW_HDMI_QP_H__
|
|
+
|
|
+#include <linux/bits.h>
|
|
+
|
|
+/* Main Unit Registers */
|
|
+#define CORE_ID 0x0
|
|
+#define VER_NUMBER 0x4
|
|
+#define VER_TYPE 0x8
|
|
+#define CONFIG_REG 0xc
|
|
+#define CONFIG_CEC BIT(28)
|
|
+#define CONFIG_AUD_UD BIT(23)
|
|
+#define CORE_TIMESTAMP_HHMM 0x14
|
|
+#define CORE_TIMESTAMP_MMDD 0x18
|
|
+#define CORE_TIMESTAMP_YYYY 0x1c
|
|
+/* Reset Manager Registers */
|
|
+#define GLOBAL_SWRESET_REQUEST 0x40
|
|
+#define EARCRX_CMDC_SWINIT_P BIT(27)
|
|
+#define AVP_DATAPATH_PACKET_AUDIO_SWINIT_P BIT(10)
|
|
+#define GLOBAL_SWDISABLE 0x44
|
|
+#define CEC_SWDISABLE BIT(17)
|
|
+#define AVP_DATAPATH_PACKET_AUDIO_SWDISABLE BIT(10)
|
|
+#define AVP_DATAPATH_VIDEO_SWDISABLE BIT(6)
|
|
+#define RESET_MANAGER_CONFIG0 0x48
|
|
+#define RESET_MANAGER_STATUS0 0x50
|
|
+#define RESET_MANAGER_STATUS1 0x54
|
|
+#define RESET_MANAGER_STATUS2 0x58
|
|
+/* Timer Base Registers */
|
|
+#define TIMER_BASE_CONFIG0 0x80
|
|
+#define TIMER_BASE_STATUS0 0x84
|
|
+/* CMU Registers */
|
|
+#define CMU_CONFIG0 0xa0
|
|
+#define CMU_CONFIG1 0xa4
|
|
+#define CMU_CONFIG2 0xa8
|
|
+#define CMU_CONFIG3 0xac
|
|
+#define CMU_STATUS 0xb0
|
|
+#define DISPLAY_CLK_MONITOR 0x3f
|
|
+#define DISPLAY_CLK_LOCKED 0X15
|
|
+#define EARC_BPCLK_OFF BIT(9)
|
|
+#define AUDCLK_OFF BIT(7)
|
|
+#define LINKQPCLK_OFF BIT(5)
|
|
+#define VIDQPCLK_OFF BIT(3)
|
|
+#define IPI_CLK_OFF BIT(1)
|
|
+#define CMU_IPI_CLK_FREQ 0xb4
|
|
+#define CMU_VIDQPCLK_FREQ 0xb8
|
|
+#define CMU_LINKQPCLK_FREQ 0xbc
|
|
+#define CMU_AUDQPCLK_FREQ 0xc0
|
|
+#define CMU_EARC_BPCLK_FREQ 0xc4
|
|
+/* I2CM Registers */
|
|
+#define I2CM_SM_SCL_CONFIG0 0xe0
|
|
+#define I2CM_FM_SCL_CONFIG0 0xe4
|
|
+#define I2CM_CONFIG0 0xe8
|
|
+#define I2CM_CONTROL0 0xec
|
|
+#define I2CM_STATUS0 0xf0
|
|
+#define I2CM_INTERFACE_CONTROL0 0xf4
|
|
+#define I2CM_ADDR 0xff000
|
|
+#define I2CM_SLVADDR 0xfe0
|
|
+#define I2CM_WR_MASK 0x1e
|
|
+#define I2CM_EXT_READ BIT(4)
|
|
+#define I2CM_SHORT_READ BIT(3)
|
|
+#define I2CM_FM_READ BIT(2)
|
|
+#define I2CM_FM_WRITE BIT(1)
|
|
+#define I2CM_FM_EN BIT(0)
|
|
+#define I2CM_INTERFACE_CONTROL1 0xf8
|
|
+#define I2CM_SEG_PTR 0x7f80
|
|
+#define I2CM_SEG_ADDR 0x7f
|
|
+#define I2CM_INTERFACE_WRDATA_0_3 0xfc
|
|
+#define I2CM_INTERFACE_WRDATA_4_7 0x100
|
|
+#define I2CM_INTERFACE_WRDATA_8_11 0x104
|
|
+#define I2CM_INTERFACE_WRDATA_12_15 0x108
|
|
+#define I2CM_INTERFACE_RDDATA_0_3 0x10c
|
|
+#define I2CM_INTERFACE_RDDATA_4_7 0x110
|
|
+#define I2CM_INTERFACE_RDDATA_8_11 0x114
|
|
+#define I2CM_INTERFACE_RDDATA_12_15 0x118
|
|
+/* SCDC Registers */
|
|
+#define SCDC_CONFIG0 0x140
|
|
+#define SCDC_I2C_FM_EN BIT(12)
|
|
+#define SCDC_UPD_FLAGS_AUTO_CLR BIT(6)
|
|
+#define SCDC_UPD_FLAGS_POLL_EN BIT(4)
|
|
+#define SCDC_CONTROL0 0x148
|
|
+#define SCDC_STATUS0 0x150
|
|
+#define STATUS_UPDATE BIT(0)
|
|
+#define FRL_START BIT(4)
|
|
+#define FLT_UPDATE BIT(5)
|
|
+/* FLT Registers */
|
|
+#define FLT_CONFIG0 0x160
|
|
+#define FLT_CONFIG1 0x164
|
|
+#define FLT_CONFIG2 0x168
|
|
+#define FLT_CONTROL0 0x170
|
|
+/* Main Unit 2 Registers */
|
|
+#define MAINUNIT_STATUS0 0x180
|
|
+/* Video Interface Registers */
|
|
+#define VIDEO_INTERFACE_CONFIG0 0x800
|
|
+#define VIDEO_INTERFACE_CONFIG1 0x804
|
|
+#define VIDEO_INTERFACE_CONFIG2 0x808
|
|
+#define VIDEO_INTERFACE_CONTROL0 0x80c
|
|
+#define VIDEO_INTERFACE_STATUS0 0x814
|
|
+/* Video Packing Registers */
|
|
+#define VIDEO_PACKING_CONFIG0 0x81c
|
|
+/* Audio Interface Registers */
|
|
+#define AUDIO_INTERFACE_CONFIG0 0x820
|
|
+#define AUD_IF_SEL_MSK 0x3
|
|
+#define AUD_IF_SPDIF 0x2
|
|
+#define AUD_IF_I2S 0x1
|
|
+#define AUD_IF_PAI 0x0
|
|
+#define AUD_FIFO_INIT_ON_OVF_MSK BIT(2)
|
|
+#define AUD_FIFO_INIT_ON_OVF_EN BIT(2)
|
|
+#define I2S_LINES_EN_MSK GENMASK(7, 4)
|
|
+#define I2S_LINES_EN(x) BIT((x) + 4)
|
|
+#define I2S_BPCUV_RCV_MSK BIT(12)
|
|
+#define I2S_BPCUV_RCV_EN BIT(12)
|
|
+#define I2S_BPCUV_RCV_DIS 0
|
|
+#define SPDIF_LINES_EN GENMASK(19, 16)
|
|
+#define AUD_FORMAT_MSK GENMASK(26, 24)
|
|
+#define AUD_3DOBA (0x7 << 24)
|
|
+#define AUD_3DASP (0x6 << 24)
|
|
+#define AUD_MSOBA (0x5 << 24)
|
|
+#define AUD_MSASP (0x4 << 24)
|
|
+#define AUD_HBR (0x3 << 24)
|
|
+#define AUD_DST (0x2 << 24)
|
|
+#define AUD_OBA (0x1 << 24)
|
|
+#define AUD_ASP (0x0 << 24)
|
|
+#define AUDIO_INTERFACE_CONFIG1 0x824
|
|
+#define AUDIO_INTERFACE_CONTROL0 0x82c
|
|
+#define AUDIO_FIFO_CLR_P BIT(0)
|
|
+#define AUDIO_INTERFACE_STATUS0 0x834
|
|
+/* Frame Composer Registers */
|
|
+#define FRAME_COMPOSER_CONFIG0 0x840
|
|
+#define FRAME_COMPOSER_CONFIG1 0x844
|
|
+#define FRAME_COMPOSER_CONFIG2 0x848
|
|
+#define FRAME_COMPOSER_CONFIG3 0x84c
|
|
+#define FRAME_COMPOSER_CONFIG4 0x850
|
|
+#define FRAME_COMPOSER_CONFIG5 0x854
|
|
+#define FRAME_COMPOSER_CONFIG6 0x858
|
|
+#define FRAME_COMPOSER_CONFIG7 0x85c
|
|
+#define FRAME_COMPOSER_CONFIG8 0x860
|
|
+#define FRAME_COMPOSER_CONFIG9 0x864
|
|
+#define FRAME_COMPOSER_CONTROL0 0x86c
|
|
+/* Video Monitor Registers */
|
|
+#define VIDEO_MONITOR_CONFIG0 0x880
|
|
+#define VIDEO_MONITOR_STATUS0 0x884
|
|
+#define VIDEO_MONITOR_STATUS1 0x888
|
|
+#define VIDEO_MONITOR_STATUS2 0x88c
|
|
+#define VIDEO_MONITOR_STATUS3 0x890
|
|
+#define VIDEO_MONITOR_STATUS4 0x894
|
|
+#define VIDEO_MONITOR_STATUS5 0x898
|
|
+#define VIDEO_MONITOR_STATUS6 0x89c
|
|
+/* HDCP2 Logic Registers */
|
|
+#define HDCP2LOGIC_CONFIG0 0x8e0
|
|
+#define HDCP2_BYPASS BIT(0)
|
|
+#define HDCP2LOGIC_ESM_GPIO_IN 0x8e4
|
|
+#define HDCP2LOGIC_ESM_GPIO_OUT 0x8e8
|
|
+/* HDCP14 Registers */
|
|
+#define HDCP14_CONFIG0 0x900
|
|
+#define HDCP14_CONFIG1 0x904
|
|
+#define HDCP14_CONFIG2 0x908
|
|
+#define HDCP14_CONFIG3 0x90c
|
|
+#define HDCP14_KEY_SEED 0x914
|
|
+#define HDCP14_KEY_H 0x918
|
|
+#define HDCP14_KEY_L 0x91c
|
|
+#define HDCP14_KEY_STATUS 0x920
|
|
+#define HDCP14_AKSV_H 0x924
|
|
+#define HDCP14_AKSV_L 0x928
|
|
+#define HDCP14_AN_H 0x92c
|
|
+#define HDCP14_AN_L 0x930
|
|
+#define HDCP14_STATUS0 0x934
|
|
+#define HDCP14_STATUS1 0x938
|
|
+/* Scrambler Registers */
|
|
+#define SCRAMB_CONFIG0 0x960
|
|
+/* Video Configuration Registers */
|
|
+#define LINK_CONFIG0 0x968
|
|
+#define OPMODE_FRL_4LANES BIT(8)
|
|
+#define OPMODE_DVI BIT(4)
|
|
+#define OPMODE_FRL BIT(0)
|
|
+/* TMDS FIFO Registers */
|
|
+#define TMDS_FIFO_CONFIG0 0x970
|
|
+#define TMDS_FIFO_CONTROL0 0x974
|
|
+/* FRL RSFEC Registers */
|
|
+#define FRL_RSFEC_CONFIG0 0xa20
|
|
+#define FRL_RSFEC_STATUS0 0xa30
|
|
+/* FRL Packetizer Registers */
|
|
+#define FRL_PKTZ_CONFIG0 0xa40
|
|
+#define FRL_PKTZ_CONTROL0 0xa44
|
|
+#define FRL_PKTZ_CONTROL1 0xa50
|
|
+#define FRL_PKTZ_STATUS1 0xa54
|
|
+/* Packet Scheduler Registers */
|
|
+#define PKTSCHED_CONFIG0 0xa80
|
|
+#define PKTSCHED_PRQUEUE0_CONFIG0 0xa84
|
|
+#define PKTSCHED_PRQUEUE1_CONFIG0 0xa88
|
|
+#define PKTSCHED_PRQUEUE2_CONFIG0 0xa8c
|
|
+#define PKTSCHED_PRQUEUE2_CONFIG1 0xa90
|
|
+#define PKTSCHED_PRQUEUE2_CONFIG2 0xa94
|
|
+#define PKTSCHED_PKT_CONFIG0 0xa98
|
|
+#define PKTSCHED_PKT_CONFIG1 0xa9c
|
|
+#define PKTSCHED_DRMI_FIELDRATE BIT(13)
|
|
+#define PKTSCHED_AVI_FIELDRATE BIT(12)
|
|
+#define PKTSCHED_PKT_CONFIG2 0xaa0
|
|
+#define PKTSCHED_PKT_CONFIG3 0xaa4
|
|
+#define PKTSCHED_PKT_EN 0xaa8
|
|
+#define PKTSCHED_DRMI_TX_EN BIT(17)
|
|
+#define PKTSCHED_AUDI_TX_EN BIT(15)
|
|
+#define PKTSCHED_AVI_TX_EN BIT(13)
|
|
+#define PKTSCHED_EMP_CVTEM_TX_EN BIT(10)
|
|
+#define PKTSCHED_AMD_TX_EN BIT(8)
|
|
+#define PKTSCHED_GCP_TX_EN BIT(3)
|
|
+#define PKTSCHED_AUDS_TX_EN BIT(2)
|
|
+#define PKTSCHED_ACR_TX_EN BIT(1)
|
|
+#define PKTSCHED_NULL_TX_EN BIT(0)
|
|
+#define PKTSCHED_PKT_CONTROL0 0xaac
|
|
+#define PKTSCHED_PKT_SEND 0xab0
|
|
+#define PKTSCHED_PKT_STATUS0 0xab4
|
|
+#define PKTSCHED_PKT_STATUS1 0xab8
|
|
+#define PKT_NULL_CONTENTS0 0xb00
|
|
+#define PKT_NULL_CONTENTS1 0xb04
|
|
+#define PKT_NULL_CONTENTS2 0xb08
|
|
+#define PKT_NULL_CONTENTS3 0xb0c
|
|
+#define PKT_NULL_CONTENTS4 0xb10
|
|
+#define PKT_NULL_CONTENTS5 0xb14
|
|
+#define PKT_NULL_CONTENTS6 0xb18
|
|
+#define PKT_NULL_CONTENTS7 0xb1c
|
|
+#define PKT_ACP_CONTENTS0 0xb20
|
|
+#define PKT_ACP_CONTENTS1 0xb24
|
|
+#define PKT_ACP_CONTENTS2 0xb28
|
|
+#define PKT_ACP_CONTENTS3 0xb2c
|
|
+#define PKT_ACP_CONTENTS4 0xb30
|
|
+#define PKT_ACP_CONTENTS5 0xb34
|
|
+#define PKT_ACP_CONTENTS6 0xb38
|
|
+#define PKT_ACP_CONTENTS7 0xb3c
|
|
+#define PKT_ISRC1_CONTENTS0 0xb40
|
|
+#define PKT_ISRC1_CONTENTS1 0xb44
|
|
+#define PKT_ISRC1_CONTENTS2 0xb48
|
|
+#define PKT_ISRC1_CONTENTS3 0xb4c
|
|
+#define PKT_ISRC1_CONTENTS4 0xb50
|
|
+#define PKT_ISRC1_CONTENTS5 0xb54
|
|
+#define PKT_ISRC1_CONTENTS6 0xb58
|
|
+#define PKT_ISRC1_CONTENTS7 0xb5c
|
|
+#define PKT_ISRC2_CONTENTS0 0xb60
|
|
+#define PKT_ISRC2_CONTENTS1 0xb64
|
|
+#define PKT_ISRC2_CONTENTS2 0xb68
|
|
+#define PKT_ISRC2_CONTENTS3 0xb6c
|
|
+#define PKT_ISRC2_CONTENTS4 0xb70
|
|
+#define PKT_ISRC2_CONTENTS5 0xb74
|
|
+#define PKT_ISRC2_CONTENTS6 0xb78
|
|
+#define PKT_ISRC2_CONTENTS7 0xb7c
|
|
+#define PKT_GMD_CONTENTS0 0xb80
|
|
+#define PKT_GMD_CONTENTS1 0xb84
|
|
+#define PKT_GMD_CONTENTS2 0xb88
|
|
+#define PKT_GMD_CONTENTS3 0xb8c
|
|
+#define PKT_GMD_CONTENTS4 0xb90
|
|
+#define PKT_GMD_CONTENTS5 0xb94
|
|
+#define PKT_GMD_CONTENTS6 0xb98
|
|
+#define PKT_GMD_CONTENTS7 0xb9c
|
|
+#define PKT_AMD_CONTENTS0 0xba0
|
|
+#define PKT_AMD_CONTENTS1 0xba4
|
|
+#define PKT_AMD_CONTENTS2 0xba8
|
|
+#define PKT_AMD_CONTENTS3 0xbac
|
|
+#define PKT_AMD_CONTENTS4 0xbb0
|
|
+#define PKT_AMD_CONTENTS5 0xbb4
|
|
+#define PKT_AMD_CONTENTS6 0xbb8
|
|
+#define PKT_AMD_CONTENTS7 0xbbc
|
|
+#define PKT_VSI_CONTENTS0 0xbc0
|
|
+#define PKT_VSI_CONTENTS1 0xbc4
|
|
+#define PKT_VSI_CONTENTS2 0xbc8
|
|
+#define PKT_VSI_CONTENTS3 0xbcc
|
|
+#define PKT_VSI_CONTENTS4 0xbd0
|
|
+#define PKT_VSI_CONTENTS5 0xbd4
|
|
+#define PKT_VSI_CONTENTS6 0xbd8
|
|
+#define PKT_VSI_CONTENTS7 0xbdc
|
|
+#define PKT_AVI_CONTENTS0 0xbe0
|
|
+#define HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT BIT(4)
|
|
+#define HDMI_FC_AVICONF0_BAR_DATA_VERT_BAR 0x04
|
|
+#define HDMI_FC_AVICONF0_BAR_DATA_HORIZ_BAR 0x08
|
|
+#define HDMI_FC_AVICONF2_IT_CONTENT_VALID 0x80
|
|
+#define PKT_AVI_CONTENTS1 0xbe4
|
|
+#define PKT_AVI_CONTENTS2 0xbe8
|
|
+#define PKT_AVI_CONTENTS3 0xbec
|
|
+#define PKT_AVI_CONTENTS4 0xbf0
|
|
+#define PKT_AVI_CONTENTS5 0xbf4
|
|
+#define PKT_AVI_CONTENTS6 0xbf8
|
|
+#define PKT_AVI_CONTENTS7 0xbfc
|
|
+#define PKT_SPDI_CONTENTS0 0xc00
|
|
+#define PKT_SPDI_CONTENTS1 0xc04
|
|
+#define PKT_SPDI_CONTENTS2 0xc08
|
|
+#define PKT_SPDI_CONTENTS3 0xc0c
|
|
+#define PKT_SPDI_CONTENTS4 0xc10
|
|
+#define PKT_SPDI_CONTENTS5 0xc14
|
|
+#define PKT_SPDI_CONTENTS6 0xc18
|
|
+#define PKT_SPDI_CONTENTS7 0xc1c
|
|
+#define PKT_AUDI_CONTENTS0 0xc20
|
|
+#define PKT_AUDI_CONTENTS1 0xc24
|
|
+#define PKT_AUDI_CONTENTS2 0xc28
|
|
+#define PKT_AUDI_CONTENTS3 0xc2c
|
|
+#define PKT_AUDI_CONTENTS4 0xc30
|
|
+#define PKT_AUDI_CONTENTS5 0xc34
|
|
+#define PKT_AUDI_CONTENTS6 0xc38
|
|
+#define PKT_AUDI_CONTENTS7 0xc3c
|
|
+#define PKT_NVI_CONTENTS0 0xc40
|
|
+#define PKT_NVI_CONTENTS1 0xc44
|
|
+#define PKT_NVI_CONTENTS2 0xc48
|
|
+#define PKT_NVI_CONTENTS3 0xc4c
|
|
+#define PKT_NVI_CONTENTS4 0xc50
|
|
+#define PKT_NVI_CONTENTS5 0xc54
|
|
+#define PKT_NVI_CONTENTS6 0xc58
|
|
+#define PKT_NVI_CONTENTS7 0xc5c
|
|
+#define PKT_DRMI_CONTENTS0 0xc60
|
|
+#define PKT_DRMI_CONTENTS1 0xc64
|
|
+#define PKT_DRMI_CONTENTS2 0xc68
|
|
+#define PKT_DRMI_CONTENTS3 0xc6c
|
|
+#define PKT_DRMI_CONTENTS4 0xc70
|
|
+#define PKT_DRMI_CONTENTS5 0xc74
|
|
+#define PKT_DRMI_CONTENTS6 0xc78
|
|
+#define PKT_DRMI_CONTENTS7 0xc7c
|
|
+#define PKT_GHDMI1_CONTENTS0 0xc80
|
|
+#define PKT_GHDMI1_CONTENTS1 0xc84
|
|
+#define PKT_GHDMI1_CONTENTS2 0xc88
|
|
+#define PKT_GHDMI1_CONTENTS3 0xc8c
|
|
+#define PKT_GHDMI1_CONTENTS4 0xc90
|
|
+#define PKT_GHDMI1_CONTENTS5 0xc94
|
|
+#define PKT_GHDMI1_CONTENTS6 0xc98
|
|
+#define PKT_GHDMI1_CONTENTS7 0xc9c
|
|
+#define PKT_GHDMI2_CONTENTS0 0xca0
|
|
+#define PKT_GHDMI2_CONTENTS1 0xca4
|
|
+#define PKT_GHDMI2_CONTENTS2 0xca8
|
|
+#define PKT_GHDMI2_CONTENTS3 0xcac
|
|
+#define PKT_GHDMI2_CONTENTS4 0xcb0
|
|
+#define PKT_GHDMI2_CONTENTS5 0xcb4
|
|
+#define PKT_GHDMI2_CONTENTS6 0xcb8
|
|
+#define PKT_GHDMI2_CONTENTS7 0xcbc
|
|
+/* EMP Packetizer Registers */
|
|
+#define PKT_EMP_CONFIG0 0xce0
|
|
+#define PKT_EMP_CONTROL0 0xcec
|
|
+#define PKT_EMP_CONTROL1 0xcf0
|
|
+#define PKT_EMP_CONTROL2 0xcf4
|
|
+#define PKT_EMP_VTEM_CONTENTS0 0xd00
|
|
+#define PKT_EMP_VTEM_CONTENTS1 0xd04
|
|
+#define PKT_EMP_VTEM_CONTENTS2 0xd08
|
|
+#define PKT_EMP_VTEM_CONTENTS3 0xd0c
|
|
+#define PKT_EMP_VTEM_CONTENTS4 0xd10
|
|
+#define PKT_EMP_VTEM_CONTENTS5 0xd14
|
|
+#define PKT_EMP_VTEM_CONTENTS6 0xd18
|
|
+#define PKT_EMP_VTEM_CONTENTS7 0xd1c
|
|
+#define PKT0_EMP_CVTEM_CONTENTS0 0xd20
|
|
+#define PKT0_EMP_CVTEM_CONTENTS1 0xd24
|
|
+#define PKT0_EMP_CVTEM_CONTENTS2 0xd28
|
|
+#define PKT0_EMP_CVTEM_CONTENTS3 0xd2c
|
|
+#define PKT0_EMP_CVTEM_CONTENTS4 0xd30
|
|
+#define PKT0_EMP_CVTEM_CONTENTS5 0xd34
|
|
+#define PKT0_EMP_CVTEM_CONTENTS6 0xd38
|
|
+#define PKT0_EMP_CVTEM_CONTENTS7 0xd3c
|
|
+#define PKT1_EMP_CVTEM_CONTENTS0 0xd40
|
|
+#define PKT1_EMP_CVTEM_CONTENTS1 0xd44
|
|
+#define PKT1_EMP_CVTEM_CONTENTS2 0xd48
|
|
+#define PKT1_EMP_CVTEM_CONTENTS3 0xd4c
|
|
+#define PKT1_EMP_CVTEM_CONTENTS4 0xd50
|
|
+#define PKT1_EMP_CVTEM_CONTENTS5 0xd54
|
|
+#define PKT1_EMP_CVTEM_CONTENTS6 0xd58
|
|
+#define PKT1_EMP_CVTEM_CONTENTS7 0xd5c
|
|
+#define PKT2_EMP_CVTEM_CONTENTS0 0xd60
|
|
+#define PKT2_EMP_CVTEM_CONTENTS1 0xd64
|
|
+#define PKT2_EMP_CVTEM_CONTENTS2 0xd68
|
|
+#define PKT2_EMP_CVTEM_CONTENTS3 0xd6c
|
|
+#define PKT2_EMP_CVTEM_CONTENTS4 0xd70
|
|
+#define PKT2_EMP_CVTEM_CONTENTS5 0xd74
|
|
+#define PKT2_EMP_CVTEM_CONTENTS6 0xd78
|
|
+#define PKT2_EMP_CVTEM_CONTENTS7 0xd7c
|
|
+#define PKT3_EMP_CVTEM_CONTENTS0 0xd80
|
|
+#define PKT3_EMP_CVTEM_CONTENTS1 0xd84
|
|
+#define PKT3_EMP_CVTEM_CONTENTS2 0xd88
|
|
+#define PKT3_EMP_CVTEM_CONTENTS3 0xd8c
|
|
+#define PKT3_EMP_CVTEM_CONTENTS4 0xd90
|
|
+#define PKT3_EMP_CVTEM_CONTENTS5 0xd94
|
|
+#define PKT3_EMP_CVTEM_CONTENTS6 0xd98
|
|
+#define PKT3_EMP_CVTEM_CONTENTS7 0xd9c
|
|
+#define PKT4_EMP_CVTEM_CONTENTS0 0xda0
|
|
+#define PKT4_EMP_CVTEM_CONTENTS1 0xda4
|
|
+#define PKT4_EMP_CVTEM_CONTENTS2 0xda8
|
|
+#define PKT4_EMP_CVTEM_CONTENTS3 0xdac
|
|
+#define PKT4_EMP_CVTEM_CONTENTS4 0xdb0
|
|
+#define PKT4_EMP_CVTEM_CONTENTS5 0xdb4
|
|
+#define PKT4_EMP_CVTEM_CONTENTS6 0xdb8
|
|
+#define PKT4_EMP_CVTEM_CONTENTS7 0xdbc
|
|
+#define PKT5_EMP_CVTEM_CONTENTS0 0xdc0
|
|
+#define PKT5_EMP_CVTEM_CONTENTS1 0xdc4
|
|
+#define PKT5_EMP_CVTEM_CONTENTS2 0xdc8
|
|
+#define PKT5_EMP_CVTEM_CONTENTS3 0xdcc
|
|
+#define PKT5_EMP_CVTEM_CONTENTS4 0xdd0
|
|
+#define PKT5_EMP_CVTEM_CONTENTS5 0xdd4
|
|
+#define PKT5_EMP_CVTEM_CONTENTS6 0xdd8
|
|
+#define PKT5_EMP_CVTEM_CONTENTS7 0xddc
|
|
+/* Audio Packetizer Registers */
|
|
+#define AUDPKT_CONTROL0 0xe20
|
|
+#define AUDPKT_PBIT_FORCE_EN_MASK BIT(12)
|
|
+#define AUDPKT_PBIT_FORCE_EN BIT(12)
|
|
+#define AUDPKT_CHSTATUS_OVR_EN_MASK BIT(0)
|
|
+#define AUDPKT_CHSTATUS_OVR_EN BIT(0)
|
|
+#define AUDPKT_CONTROL1 0xe24
|
|
+#define AUDPKT_ACR_CONTROL0 0xe40
|
|
+#define AUDPKT_ACR_N_VALUE 0xfffff
|
|
+#define AUDPKT_ACR_CONTROL1 0xe44
|
|
+#define AUDPKT_ACR_CTS_OVR_VAL_MSK GENMASK(23, 4)
|
|
+#define AUDPKT_ACR_CTS_OVR_VAL(x) ((x) << 4)
|
|
+#define AUDPKT_ACR_CTS_OVR_EN_MSK BIT(1)
|
|
+#define AUDPKT_ACR_CTS_OVR_EN BIT(1)
|
|
+#define AUDPKT_ACR_STATUS0 0xe4c
|
|
+#define AUDPKT_CHSTATUS_OVR0 0xe60
|
|
+#define AUDPKT_CHSTATUS_OVR1 0xe64
|
|
+/* IEC60958 Byte 3: Sampleing frenuency Bits 24 to 27 */
|
|
+#define AUDPKT_CHSTATUS_SR_MASK GENMASK(3, 0)
|
|
+#define AUDPKT_CHSTATUS_SR_22050 0x4
|
|
+#define AUDPKT_CHSTATUS_SR_24000 0x6
|
|
+#define AUDPKT_CHSTATUS_SR_32000 0x3
|
|
+#define AUDPKT_CHSTATUS_SR_44100 0x0
|
|
+#define AUDPKT_CHSTATUS_SR_48000 0x2
|
|
+#define AUDPKT_CHSTATUS_SR_88200 0x8
|
|
+#define AUDPKT_CHSTATUS_SR_96000 0xa
|
|
+#define AUDPKT_CHSTATUS_SR_176400 0xc
|
|
+#define AUDPKT_CHSTATUS_SR_192000 0xe
|
|
+#define AUDPKT_CHSTATUS_SR_768000 0x9
|
|
+#define AUDPKT_CHSTATUS_SR_NOT_INDICATED 0x1
|
|
+/* IEC60958 Byte 4: Original Sampleing frenuency Bits 36 to 39 */
|
|
+#define AUDPKT_CHSTATUS_0SR_MASK GENMASK(15, 12)
|
|
+#define AUDPKT_CHSTATUS_OSR_8000 0x6
|
|
+#define AUDPKT_CHSTATUS_OSR_11025 0xa
|
|
+#define AUDPKT_CHSTATUS_OSR_12000 0x2
|
|
+#define AUDPKT_CHSTATUS_OSR_16000 0x8
|
|
+#define AUDPKT_CHSTATUS_OSR_22050 0xb
|
|
+#define AUDPKT_CHSTATUS_OSR_24000 0x9
|
|
+#define AUDPKT_CHSTATUS_OSR_32000 0xc
|
|
+#define AUDPKT_CHSTATUS_OSR_44100 0xf
|
|
+#define AUDPKT_CHSTATUS_OSR_48000 0xd
|
|
+#define AUDPKT_CHSTATUS_OSR_88200 0x7
|
|
+#define AUDPKT_CHSTATUS_OSR_96000 0x5
|
|
+#define AUDPKT_CHSTATUS_OSR_176400 0x3
|
|
+#define AUDPKT_CHSTATUS_OSR_192000 0x1
|
|
+#define AUDPKT_CHSTATUS_OSR_NOT_INDICATED 0x0
|
|
+#define AUDPKT_CHSTATUS_OVR2 0xe68
|
|
+#define AUDPKT_CHSTATUS_OVR3 0xe6c
|
|
+#define AUDPKT_CHSTATUS_OVR4 0xe70
|
|
+#define AUDPKT_CHSTATUS_OVR5 0xe74
|
|
+#define AUDPKT_CHSTATUS_OVR6 0xe78
|
|
+#define AUDPKT_CHSTATUS_OVR7 0xe7c
|
|
+#define AUDPKT_CHSTATUS_OVR8 0xe80
|
|
+#define AUDPKT_CHSTATUS_OVR9 0xe84
|
|
+#define AUDPKT_CHSTATUS_OVR10 0xe88
|
|
+#define AUDPKT_CHSTATUS_OVR11 0xe8c
|
|
+#define AUDPKT_CHSTATUS_OVR12 0xe90
|
|
+#define AUDPKT_CHSTATUS_OVR13 0xe94
|
|
+#define AUDPKT_CHSTATUS_OVR14 0xe98
|
|
+#define AUDPKT_USRDATA_OVR_MSG_GENERIC0 0xea0
|
|
+#define AUDPKT_USRDATA_OVR_MSG_GENERIC1 0xea4
|
|
+#define AUDPKT_USRDATA_OVR_MSG_GENERIC2 0xea8
|
|
+#define AUDPKT_USRDATA_OVR_MSG_GENERIC3 0xeac
|
|
+#define AUDPKT_USRDATA_OVR_MSG_GENERIC4 0xeb0
|
|
+#define AUDPKT_USRDATA_OVR_MSG_GENERIC5 0xeb4
|
|
+#define AUDPKT_USRDATA_OVR_MSG_GENERIC6 0xeb8
|
|
+#define AUDPKT_USRDATA_OVR_MSG_GENERIC7 0xebc
|
|
+#define AUDPKT_USRDATA_OVR_MSG_GENERIC8 0xec0
|
|
+#define AUDPKT_USRDATA_OVR_MSG_GENERIC9 0xec4
|
|
+#define AUDPKT_USRDATA_OVR_MSG_GENERIC10 0xec8
|
|
+#define AUDPKT_USRDATA_OVR_MSG_GENERIC11 0xecc
|
|
+#define AUDPKT_USRDATA_OVR_MSG_GENERIC12 0xed0
|
|
+#define AUDPKT_USRDATA_OVR_MSG_GENERIC13 0xed4
|
|
+#define AUDPKT_USRDATA_OVR_MSG_GENERIC14 0xed8
|
|
+#define AUDPKT_USRDATA_OVR_MSG_GENERIC15 0xedc
|
|
+#define AUDPKT_USRDATA_OVR_MSG_GENERIC16 0xee0
|
|
+#define AUDPKT_USRDATA_OVR_MSG_GENERIC17 0xee4
|
|
+#define AUDPKT_USRDATA_OVR_MSG_GENERIC18 0xee8
|
|
+#define AUDPKT_USRDATA_OVR_MSG_GENERIC19 0xeec
|
|
+#define AUDPKT_USRDATA_OVR_MSG_GENERIC20 0xef0
|
|
+#define AUDPKT_USRDATA_OVR_MSG_GENERIC21 0xef4
|
|
+#define AUDPKT_USRDATA_OVR_MSG_GENERIC22 0xef8
|
|
+#define AUDPKT_USRDATA_OVR_MSG_GENERIC23 0xefc
|
|
+#define AUDPKT_USRDATA_OVR_MSG_GENERIC24 0xf00
|
|
+#define AUDPKT_USRDATA_OVR_MSG_GENERIC25 0xf04
|
|
+#define AUDPKT_USRDATA_OVR_MSG_GENERIC26 0xf08
|
|
+#define AUDPKT_USRDATA_OVR_MSG_GENERIC27 0xf0c
|
|
+#define AUDPKT_USRDATA_OVR_MSG_GENERIC28 0xf10
|
|
+#define AUDPKT_USRDATA_OVR_MSG_GENERIC29 0xf14
|
|
+#define AUDPKT_USRDATA_OVR_MSG_GENERIC30 0xf18
|
|
+#define AUDPKT_USRDATA_OVR_MSG_GENERIC31 0xf1c
|
|
+#define AUDPKT_USRDATA_OVR_MSG_GENERIC32 0xf20
|
|
+#define AUDPKT_VBIT_OVR0 0xf24
|
|
+/* CEC Registers */
|
|
+#define CEC_TX_CONTROL 0x1000
|
|
+#define CEC_STATUS 0x1004
|
|
+#define CEC_CONFIG 0x1008
|
|
+#define CEC_ADDR 0x100c
|
|
+#define CEC_TX_COUNT 0x1020
|
|
+#define CEC_TX_DATA3_0 0x1024
|
|
+#define CEC_TX_DATA7_4 0x1028
|
|
+#define CEC_TX_DATA11_8 0x102c
|
|
+#define CEC_TX_DATA15_12 0x1030
|
|
+#define CEC_RX_COUNT_STATUS 0x1040
|
|
+#define CEC_RX_DATA3_0 0x1044
|
|
+#define CEC_RX_DATA7_4 0x1048
|
|
+#define CEC_RX_DATA11_8 0x104c
|
|
+#define CEC_RX_DATA15_12 0x1050
|
|
+#define CEC_LOCK_CONTROL 0x1054
|
|
+#define CEC_RXQUAL_BITTIME_CONFIG 0x1060
|
|
+#define CEC_RX_BITTIME_CONFIG 0x1064
|
|
+#define CEC_TX_BITTIME_CONFIG 0x1068
|
|
+/* eARC RX CMDC Registers */
|
|
+#define EARCRX_CMDC_CONFIG0 0x1800
|
|
+#define EARCRX_XACTREAD_STOP_CFG BIT(26)
|
|
+#define EARCRX_XACTREAD_RETRY_CFG BIT(25)
|
|
+#define EARCRX_CMDC_DSCVR_EARCVALID0_TO_DISC1 BIT(24)
|
|
+#define EARCRX_CMDC_XACT_RESTART_EN BIT(18)
|
|
+#define EARCRX_CMDC_CONFIG1 0x1804
|
|
+#define EARCRX_CMDC_CONTROL 0x1808
|
|
+#define EARCRX_CMDC_HEARTBEAT_LOSS_EN BIT(4)
|
|
+#define EARCRX_CMDC_DISCOVERY_EN BIT(3)
|
|
+#define EARCRX_CONNECTOR_HPD BIT(1)
|
|
+#define EARCRX_CMDC_WHITELIST0_CONFIG 0x180c
|
|
+#define EARCRX_CMDC_WHITELIST1_CONFIG 0x1810
|
|
+#define EARCRX_CMDC_WHITELIST2_CONFIG 0x1814
|
|
+#define EARCRX_CMDC_WHITELIST3_CONFIG 0x1818
|
|
+#define EARCRX_CMDC_STATUS 0x181c
|
|
+#define EARCRX_CMDC_XACT_INFO 0x1820
|
|
+#define EARCRX_CMDC_XACT_ACTION 0x1824
|
|
+#define EARCRX_CMDC_HEARTBEAT_RXSTAT_SE 0x1828
|
|
+#define EARCRX_CMDC_HEARTBEAT_STATUS 0x182c
|
|
+#define EARCRX_CMDC_XACT_WR0 0x1840
|
|
+#define EARCRX_CMDC_XACT_WR1 0x1844
|
|
+#define EARCRX_CMDC_XACT_WR2 0x1848
|
|
+#define EARCRX_CMDC_XACT_WR3 0x184c
|
|
+#define EARCRX_CMDC_XACT_WR4 0x1850
|
|
+#define EARCRX_CMDC_XACT_WR5 0x1854
|
|
+#define EARCRX_CMDC_XACT_WR6 0x1858
|
|
+#define EARCRX_CMDC_XACT_WR7 0x185c
|
|
+#define EARCRX_CMDC_XACT_WR8 0x1860
|
|
+#define EARCRX_CMDC_XACT_WR9 0x1864
|
|
+#define EARCRX_CMDC_XACT_WR10 0x1868
|
|
+#define EARCRX_CMDC_XACT_WR11 0x186c
|
|
+#define EARCRX_CMDC_XACT_WR12 0x1870
|
|
+#define EARCRX_CMDC_XACT_WR13 0x1874
|
|
+#define EARCRX_CMDC_XACT_WR14 0x1878
|
|
+#define EARCRX_CMDC_XACT_WR15 0x187c
|
|
+#define EARCRX_CMDC_XACT_WR16 0x1880
|
|
+#define EARCRX_CMDC_XACT_WR17 0x1884
|
|
+#define EARCRX_CMDC_XACT_WR18 0x1888
|
|
+#define EARCRX_CMDC_XACT_WR19 0x188c
|
|
+#define EARCRX_CMDC_XACT_WR20 0x1890
|
|
+#define EARCRX_CMDC_XACT_WR21 0x1894
|
|
+#define EARCRX_CMDC_XACT_WR22 0x1898
|
|
+#define EARCRX_CMDC_XACT_WR23 0x189c
|
|
+#define EARCRX_CMDC_XACT_WR24 0x18a0
|
|
+#define EARCRX_CMDC_XACT_WR25 0x18a4
|
|
+#define EARCRX_CMDC_XACT_WR26 0x18a8
|
|
+#define EARCRX_CMDC_XACT_WR27 0x18ac
|
|
+#define EARCRX_CMDC_XACT_WR28 0x18b0
|
|
+#define EARCRX_CMDC_XACT_WR29 0x18b4
|
|
+#define EARCRX_CMDC_XACT_WR30 0x18b8
|
|
+#define EARCRX_CMDC_XACT_WR31 0x18bc
|
|
+#define EARCRX_CMDC_XACT_WR32 0x18c0
|
|
+#define EARCRX_CMDC_XACT_WR33 0x18c4
|
|
+#define EARCRX_CMDC_XACT_WR34 0x18c8
|
|
+#define EARCRX_CMDC_XACT_WR35 0x18cc
|
|
+#define EARCRX_CMDC_XACT_WR36 0x18d0
|
|
+#define EARCRX_CMDC_XACT_WR37 0x18d4
|
|
+#define EARCRX_CMDC_XACT_WR38 0x18d8
|
|
+#define EARCRX_CMDC_XACT_WR39 0x18dc
|
|
+#define EARCRX_CMDC_XACT_WR40 0x18e0
|
|
+#define EARCRX_CMDC_XACT_WR41 0x18e4
|
|
+#define EARCRX_CMDC_XACT_WR42 0x18e8
|
|
+#define EARCRX_CMDC_XACT_WR43 0x18ec
|
|
+#define EARCRX_CMDC_XACT_WR44 0x18f0
|
|
+#define EARCRX_CMDC_XACT_WR45 0x18f4
|
|
+#define EARCRX_CMDC_XACT_WR46 0x18f8
|
|
+#define EARCRX_CMDC_XACT_WR47 0x18fc
|
|
+#define EARCRX_CMDC_XACT_WR48 0x1900
|
|
+#define EARCRX_CMDC_XACT_WR49 0x1904
|
|
+#define EARCRX_CMDC_XACT_WR50 0x1908
|
|
+#define EARCRX_CMDC_XACT_WR51 0x190c
|
|
+#define EARCRX_CMDC_XACT_WR52 0x1910
|
|
+#define EARCRX_CMDC_XACT_WR53 0x1914
|
|
+#define EARCRX_CMDC_XACT_WR54 0x1918
|
|
+#define EARCRX_CMDC_XACT_WR55 0x191c
|
|
+#define EARCRX_CMDC_XACT_WR56 0x1920
|
|
+#define EARCRX_CMDC_XACT_WR57 0x1924
|
|
+#define EARCRX_CMDC_XACT_WR58 0x1928
|
|
+#define EARCRX_CMDC_XACT_WR59 0x192c
|
|
+#define EARCRX_CMDC_XACT_WR60 0x1930
|
|
+#define EARCRX_CMDC_XACT_WR61 0x1934
|
|
+#define EARCRX_CMDC_XACT_WR62 0x1938
|
|
+#define EARCRX_CMDC_XACT_WR63 0x193c
|
|
+#define EARCRX_CMDC_XACT_WR64 0x1940
|
|
+#define EARCRX_CMDC_XACT_RD0 0x1960
|
|
+#define EARCRX_CMDC_XACT_RD1 0x1964
|
|
+#define EARCRX_CMDC_XACT_RD2 0x1968
|
|
+#define EARCRX_CMDC_XACT_RD3 0x196c
|
|
+#define EARCRX_CMDC_XACT_RD4 0x1970
|
|
+#define EARCRX_CMDC_XACT_RD5 0x1974
|
|
+#define EARCRX_CMDC_XACT_RD6 0x1978
|
|
+#define EARCRX_CMDC_XACT_RD7 0x197c
|
|
+#define EARCRX_CMDC_XACT_RD8 0x1980
|
|
+#define EARCRX_CMDC_XACT_RD9 0x1984
|
|
+#define EARCRX_CMDC_XACT_RD10 0x1988
|
|
+#define EARCRX_CMDC_XACT_RD11 0x198c
|
|
+#define EARCRX_CMDC_XACT_RD12 0x1990
|
|
+#define EARCRX_CMDC_XACT_RD13 0x1994
|
|
+#define EARCRX_CMDC_XACT_RD14 0x1998
|
|
+#define EARCRX_CMDC_XACT_RD15 0x199c
|
|
+#define EARCRX_CMDC_XACT_RD16 0x19a0
|
|
+#define EARCRX_CMDC_XACT_RD17 0x19a4
|
|
+#define EARCRX_CMDC_XACT_RD18 0x19a8
|
|
+#define EARCRX_CMDC_XACT_RD19 0x19ac
|
|
+#define EARCRX_CMDC_XACT_RD20 0x19b0
|
|
+#define EARCRX_CMDC_XACT_RD21 0x19b4
|
|
+#define EARCRX_CMDC_XACT_RD22 0x19b8
|
|
+#define EARCRX_CMDC_XACT_RD23 0x19bc
|
|
+#define EARCRX_CMDC_XACT_RD24 0x19c0
|
|
+#define EARCRX_CMDC_XACT_RD25 0x19c4
|
|
+#define EARCRX_CMDC_XACT_RD26 0x19c8
|
|
+#define EARCRX_CMDC_XACT_RD27 0x19cc
|
|
+#define EARCRX_CMDC_XACT_RD28 0x19d0
|
|
+#define EARCRX_CMDC_XACT_RD29 0x19d4
|
|
+#define EARCRX_CMDC_XACT_RD30 0x19d8
|
|
+#define EARCRX_CMDC_XACT_RD31 0x19dc
|
|
+#define EARCRX_CMDC_XACT_RD32 0x19e0
|
|
+#define EARCRX_CMDC_XACT_RD33 0x19e4
|
|
+#define EARCRX_CMDC_XACT_RD34 0x19e8
|
|
+#define EARCRX_CMDC_XACT_RD35 0x19ec
|
|
+#define EARCRX_CMDC_XACT_RD36 0x19f0
|
|
+#define EARCRX_CMDC_XACT_RD37 0x19f4
|
|
+#define EARCRX_CMDC_XACT_RD38 0x19f8
|
|
+#define EARCRX_CMDC_XACT_RD39 0x19fc
|
|
+#define EARCRX_CMDC_XACT_RD40 0x1a00
|
|
+#define EARCRX_CMDC_XACT_RD41 0x1a04
|
|
+#define EARCRX_CMDC_XACT_RD42 0x1a08
|
|
+#define EARCRX_CMDC_XACT_RD43 0x1a0c
|
|
+#define EARCRX_CMDC_XACT_RD44 0x1a10
|
|
+#define EARCRX_CMDC_XACT_RD45 0x1a14
|
|
+#define EARCRX_CMDC_XACT_RD46 0x1a18
|
|
+#define EARCRX_CMDC_XACT_RD47 0x1a1c
|
|
+#define EARCRX_CMDC_XACT_RD48 0x1a20
|
|
+#define EARCRX_CMDC_XACT_RD49 0x1a24
|
|
+#define EARCRX_CMDC_XACT_RD50 0x1a28
|
|
+#define EARCRX_CMDC_XACT_RD51 0x1a2c
|
|
+#define EARCRX_CMDC_XACT_RD52 0x1a30
|
|
+#define EARCRX_CMDC_XACT_RD53 0x1a34
|
|
+#define EARCRX_CMDC_XACT_RD54 0x1a38
|
|
+#define EARCRX_CMDC_XACT_RD55 0x1a3c
|
|
+#define EARCRX_CMDC_XACT_RD56 0x1a40
|
|
+#define EARCRX_CMDC_XACT_RD57 0x1a44
|
|
+#define EARCRX_CMDC_XACT_RD58 0x1a48
|
|
+#define EARCRX_CMDC_XACT_RD59 0x1a4c
|
|
+#define EARCRX_CMDC_XACT_RD60 0x1a50
|
|
+#define EARCRX_CMDC_XACT_RD61 0x1a54
|
|
+#define EARCRX_CMDC_XACT_RD62 0x1a58
|
|
+#define EARCRX_CMDC_XACT_RD63 0x1a5c
|
|
+#define EARCRX_CMDC_XACT_RD64 0x1a60
|
|
+#define EARCRX_CMDC_SYNC_CONFIG 0x1b00
|
|
+/* eARC RX DMAC Registers */
|
|
+#define EARCRX_DMAC_PHY_CONTROL 0x1c00
|
|
+#define EARCRX_DMAC_CONFIG 0x1c08
|
|
+#define EARCRX_DMAC_CONTROL0 0x1c0c
|
|
+#define EARCRX_DMAC_AUDIO_EN BIT(1)
|
|
+#define EARCRX_DMAC_EN BIT(0)
|
|
+#define EARCRX_DMAC_CONTROL1 0x1c10
|
|
+#define EARCRX_DMAC_STATUS 0x1c14
|
|
+#define EARCRX_DMAC_CHSTATUS0 0x1c18
|
|
+#define EARCRX_DMAC_CHSTATUS1 0x1c1c
|
|
+#define EARCRX_DMAC_CHSTATUS2 0x1c20
|
|
+#define EARCRX_DMAC_CHSTATUS3 0x1c24
|
|
+#define EARCRX_DMAC_CHSTATUS4 0x1c28
|
|
+#define EARCRX_DMAC_CHSTATUS5 0x1c2c
|
|
+#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC0 0x1c30
|
|
+#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC1 0x1c34
|
|
+#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC2 0x1c38
|
|
+#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC3 0x1c3c
|
|
+#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC4 0x1c40
|
|
+#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC5 0x1c44
|
|
+#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC6 0x1c48
|
|
+#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC7 0x1c4c
|
|
+#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC8 0x1c50
|
|
+#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC9 0x1c54
|
|
+#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC10 0x1c58
|
|
+#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC11 0x1c5c
|
|
+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT0 0x1c60
|
|
+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT1 0x1c64
|
|
+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT2 0x1c68
|
|
+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT3 0x1c6c
|
|
+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT4 0x1c70
|
|
+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT5 0x1c74
|
|
+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT6 0x1c78
|
|
+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT7 0x1c7c
|
|
+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT8 0x1c80
|
|
+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT9 0x1c84
|
|
+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT10 0x1c88
|
|
+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT11 0x1c8c
|
|
+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT0 0x1c90
|
|
+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT1 0x1c94
|
|
+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT2 0x1c98
|
|
+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT3 0x1c9c
|
|
+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT4 0x1ca0
|
|
+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT5 0x1ca4
|
|
+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT6 0x1ca8
|
|
+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT7 0x1cac
|
|
+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT8 0x1cb0
|
|
+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT9 0x1cb4
|
|
+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT10 0x1cb8
|
|
+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT11 0x1cbc
|
|
+#define EARCRX_DMAC_USRDATA_MSG_GENERIC0 0x1cc0
|
|
+#define EARCRX_DMAC_USRDATA_MSG_GENERIC1 0x1cc4
|
|
+#define EARCRX_DMAC_USRDATA_MSG_GENERIC2 0x1cc8
|
|
+#define EARCRX_DMAC_USRDATA_MSG_GENERIC3 0x1ccc
|
|
+#define EARCRX_DMAC_USRDATA_MSG_GENERIC4 0x1cd0
|
|
+#define EARCRX_DMAC_USRDATA_MSG_GENERIC5 0x1cd4
|
|
+#define EARCRX_DMAC_USRDATA_MSG_GENERIC6 0x1cd8
|
|
+#define EARCRX_DMAC_USRDATA_MSG_GENERIC7 0x1cdc
|
|
+#define EARCRX_DMAC_USRDATA_MSG_GENERIC8 0x1ce0
|
|
+#define EARCRX_DMAC_USRDATA_MSG_GENERIC9 0x1ce4
|
|
+#define EARCRX_DMAC_USRDATA_MSG_GENERIC10 0x1ce8
|
|
+#define EARCRX_DMAC_USRDATA_MSG_GENERIC11 0x1cec
|
|
+#define EARCRX_DMAC_USRDATA_MSG_GENERIC12 0x1cf0
|
|
+#define EARCRX_DMAC_USRDATA_MSG_GENERIC13 0x1cf4
|
|
+#define EARCRX_DMAC_USRDATA_MSG_GENERIC14 0x1cf8
|
|
+#define EARCRX_DMAC_USRDATA_MSG_GENERIC15 0x1cfc
|
|
+#define EARCRX_DMAC_USRDATA_MSG_GENERIC16 0x1d00
|
|
+#define EARCRX_DMAC_USRDATA_MSG_GENERIC17 0x1d04
|
|
+#define EARCRX_DMAC_USRDATA_MSG_GENERIC18 0x1d08
|
|
+#define EARCRX_DMAC_USRDATA_MSG_GENERIC19 0x1d0c
|
|
+#define EARCRX_DMAC_USRDATA_MSG_GENERIC20 0x1d10
|
|
+#define EARCRX_DMAC_USRDATA_MSG_GENERIC21 0x1d14
|
|
+#define EARCRX_DMAC_USRDATA_MSG_GENERIC22 0x1d18
|
|
+#define EARCRX_DMAC_USRDATA_MSG_GENERIC23 0x1d1c
|
|
+#define EARCRX_DMAC_USRDATA_MSG_GENERIC24 0x1d20
|
|
+#define EARCRX_DMAC_USRDATA_MSG_GENERIC25 0x1d24
|
|
+#define EARCRX_DMAC_USRDATA_MSG_GENERIC26 0x1d28
|
|
+#define EARCRX_DMAC_USRDATA_MSG_GENERIC27 0x1d2c
|
|
+#define EARCRX_DMAC_USRDATA_MSG_GENERIC28 0x1d30
|
|
+#define EARCRX_DMAC_USRDATA_MSG_GENERIC29 0x1d34
|
|
+#define EARCRX_DMAC_USRDATA_MSG_GENERIC30 0x1d38
|
|
+#define EARCRX_DMAC_USRDATA_MSG_GENERIC31 0x1d3c
|
|
+#define EARCRX_DMAC_USRDATA_MSG_GENERIC32 0x1d40
|
|
+#define EARCRX_DMAC_CHSTATUS_STREAMER0 0x1d44
|
|
+#define EARCRX_DMAC_CHSTATUS_STREAMER1 0x1d48
|
|
+#define EARCRX_DMAC_CHSTATUS_STREAMER2 0x1d4c
|
|
+#define EARCRX_DMAC_CHSTATUS_STREAMER3 0x1d50
|
|
+#define EARCRX_DMAC_CHSTATUS_STREAMER4 0x1d54
|
|
+#define EARCRX_DMAC_CHSTATUS_STREAMER5 0x1d58
|
|
+#define EARCRX_DMAC_CHSTATUS_STREAMER6 0x1d5c
|
|
+#define EARCRX_DMAC_CHSTATUS_STREAMER7 0x1d60
|
|
+#define EARCRX_DMAC_CHSTATUS_STREAMER8 0x1d64
|
|
+#define EARCRX_DMAC_CHSTATUS_STREAMER9 0x1d68
|
|
+#define EARCRX_DMAC_CHSTATUS_STREAMER10 0x1d6c
|
|
+#define EARCRX_DMAC_CHSTATUS_STREAMER11 0x1d70
|
|
+#define EARCRX_DMAC_CHSTATUS_STREAMER12 0x1d74
|
|
+#define EARCRX_DMAC_CHSTATUS_STREAMER13 0x1d78
|
|
+#define EARCRX_DMAC_CHSTATUS_STREAMER14 0x1d7c
|
|
+#define EARCRX_DMAC_USRDATA_STREAMER0 0x1d80
|
|
+/* Main Unit Interrupt Registers */
|
|
+#define MAIN_INTVEC_INDEX 0x3000
|
|
+#define MAINUNIT_0_INT_STATUS 0x3010
|
|
+#define MAINUNIT_0_INT_MASK_N 0x3014
|
|
+#define MAINUNIT_0_INT_CLEAR 0x3018
|
|
+#define MAINUNIT_0_INT_FORCE 0x301c
|
|
+#define MAINUNIT_1_INT_STATUS 0x3020
|
|
+#define FLT_EXIT_TO_LTSL_IRQ BIT(22)
|
|
+#define FLT_EXIT_TO_LTS4_IRQ BIT(21)
|
|
+#define FLT_EXIT_TO_LTSP_IRQ BIT(20)
|
|
+#define SCDC_NACK_RCVD_IRQ BIT(12)
|
|
+#define SCDC_RR_REPLY_STOP_IRQ BIT(11)
|
|
+#define SCDC_UPD_FLAGS_CLR_IRQ BIT(10)
|
|
+#define SCDC_UPD_FLAGS_CHG_IRQ BIT(9)
|
|
+#define SCDC_UPD_FLAGS_RD_IRQ BIT(8)
|
|
+#define I2CM_NACK_RCVD_IRQ BIT(2)
|
|
+#define I2CM_READ_REQUEST_IRQ BIT(1)
|
|
+#define I2CM_OP_DONE_IRQ BIT(0)
|
|
+#define MAINUNIT_1_INT_MASK_N 0x3024
|
|
+#define I2CM_NACK_RCVD_MASK_N BIT(2)
|
|
+#define I2CM_READ_REQUEST_MASK_N BIT(1)
|
|
+#define I2CM_OP_DONE_MASK_N BIT(0)
|
|
+#define MAINUNIT_1_INT_CLEAR 0x3028
|
|
+#define I2CM_NACK_RCVD_CLEAR BIT(2)
|
|
+#define I2CM_READ_REQUEST_CLEAR BIT(1)
|
|
+#define I2CM_OP_DONE_CLEAR BIT(0)
|
|
+#define MAINUNIT_1_INT_FORCE 0x302c
|
|
+/* AVPUNIT Interrupt Registers */
|
|
+#define AVP_INTVEC_INDEX 0x3800
|
|
+#define AVP_0_INT_STATUS 0x3810
|
|
+#define AVP_0_INT_MASK_N 0x3814
|
|
+#define AVP_0_INT_CLEAR 0x3818
|
|
+#define AVP_0_INT_FORCE 0x381c
|
|
+#define AVP_1_INT_STATUS 0x3820
|
|
+#define AVP_1_INT_MASK_N 0x3824
|
|
+#define HDCP14_AUTH_CHG_MASK_N BIT(6)
|
|
+#define AVP_1_INT_CLEAR 0x3828
|
|
+#define AVP_1_INT_FORCE 0x382c
|
|
+#define AVP_2_INT_STATUS 0x3830
|
|
+#define AVP_2_INT_MASK_N 0x3834
|
|
+#define AVP_2_INT_CLEAR 0x3838
|
|
+#define AVP_2_INT_FORCE 0x383c
|
|
+#define AVP_3_INT_STATUS 0x3840
|
|
+#define AVP_3_INT_MASK_N 0x3844
|
|
+#define AVP_3_INT_CLEAR 0x3848
|
|
+#define AVP_3_INT_FORCE 0x384c
|
|
+#define AVP_4_INT_STATUS 0x3850
|
|
+#define AVP_4_INT_MASK_N 0x3854
|
|
+#define AVP_4_INT_CLEAR 0x3858
|
|
+#define AVP_4_INT_FORCE 0x385c
|
|
+#define AVP_5_INT_STATUS 0x3860
|
|
+#define AVP_5_INT_MASK_N 0x3864
|
|
+#define AVP_5_INT_CLEAR 0x3868
|
|
+#define AVP_5_INT_FORCE 0x386c
|
|
+#define AVP_6_INT_STATUS 0x3870
|
|
+#define AVP_6_INT_MASK_N 0x3874
|
|
+#define AVP_6_INT_CLEAR 0x3878
|
|
+#define AVP_6_INT_FORCE 0x387c
|
|
+/* CEC Interrupt Registers */
|
|
+#define CEC_INT_STATUS 0x4000
|
|
+#define CEC_INT_MASK_N 0x4004
|
|
+#define CEC_INT_CLEAR 0x4008
|
|
+#define CEC_INT_FORCE 0x400c
|
|
+/* eARC RX Interrupt Registers */
|
|
+#define EARCRX_INTVEC_INDEX 0x4800
|
|
+#define EARCRX_0_INT_STATUS 0x4810
|
|
+#define EARCRX_CMDC_DISCOVERY_TIMEOUT_IRQ BIT(9)
|
|
+#define EARCRX_CMDC_DISCOVERY_DONE_IRQ BIT(8)
|
|
+#define EARCRX_0_INT_MASK_N 0x4814
|
|
+#define EARCRX_0_INT_CLEAR 0x4818
|
|
+#define EARCRX_0_INT_FORCE 0x481c
|
|
+#define EARCRX_1_INT_STATUS 0x4820
|
|
+#define EARCRX_1_INT_MASK_N 0x4824
|
|
+#define EARCRX_1_INT_CLEAR 0x4828
|
|
+#define EARCRX_1_INT_FORCE 0x482c
|
|
+
|
|
+#endif /* __DW_HDMI_QP_H__ */
|
|
diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
|
|
index 23c49e91f1ccf..448fadd4ba15d 100644
|
|
--- a/drivers/gpu/drm/rockchip/Kconfig
|
|
+++ b/drivers/gpu/drm/rockchip/Kconfig
|
|
@@ -8,6 +8,7 @@ config DRM_ROCKCHIP
|
|
select VIDEOMODE_HELPERS
|
|
select DRM_ANALOGIX_DP if ROCKCHIP_ANALOGIX_DP
|
|
select DRM_DW_HDMI if ROCKCHIP_DW_HDMI
|
|
+ select DRM_DW_HDMI_QP if ROCKCHIP_DW_HDMI_QP
|
|
select DRM_DW_MIPI_DSI if ROCKCHIP_DW_MIPI_DSI
|
|
select GENERIC_PHY if ROCKCHIP_DW_MIPI_DSI
|
|
select GENERIC_PHY_MIPI_DPHY if ROCKCHIP_DW_MIPI_DSI
|
|
@@ -63,6 +64,14 @@ config ROCKCHIP_DW_HDMI
|
|
enable HDMI on RK3288 or RK3399 based SoC, you should select
|
|
this option.
|
|
|
|
+config ROCKCHIP_DW_HDMI_QP
|
|
+ bool "Rockchip specific extensions for Synopsys DW HDMI QP"
|
|
+ select DRM_BRIDGE_CONNECTOR
|
|
+ help
|
|
+ This selects support for Rockchip SoC specific extensions
|
|
+ for the Synopsys DesignWare HDMI QP driver. If you want to
|
|
+ enable HDMI on RK3588 based SoC, you should select this option.
|
|
+
|
|
config ROCKCHIP_DW_MIPI_DSI
|
|
bool "Rockchip specific extensions for Synopsys DW MIPI DSI"
|
|
select GENERIC_PHY_MIPI_DPHY
|
|
diff --git a/drivers/gpu/drm/rockchip/Makefile b/drivers/gpu/drm/rockchip/Makefile
|
|
index 3ff7b21c04149..3eab662a5a1d6 100644
|
|
--- a/drivers/gpu/drm/rockchip/Makefile
|
|
+++ b/drivers/gpu/drm/rockchip/Makefile
|
|
@@ -11,6 +11,7 @@ rockchipdrm-$(CONFIG_ROCKCHIP_VOP) += rockchip_drm_vop.o rockchip_vop_reg.o
|
|
rockchipdrm-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o
|
|
rockchipdrm-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o
|
|
rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
|
|
+rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI_QP) += dw_hdmi_qp-rockchip.o
|
|
rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi-rockchip.o
|
|
rockchipdrm-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o
|
|
rockchipdrm-$(CONFIG_ROCKCHIP_LVDS) += rockchip_lvds.o
|
|
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
|
|
index 240552eb517f7..76297987f84b0 100644
|
|
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
|
|
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
|
|
@@ -91,74 +91,70 @@ static struct rockchip_hdmi *to_rockchip_hdmi(struct drm_encoder *encoder)
|
|
|
|
static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = {
|
|
{
|
|
- 27000000, {
|
|
- { 0x00b3, 0x0000},
|
|
- { 0x2153, 0x0000},
|
|
- { 0x40f3, 0x0000}
|
|
+ 30666000, {
|
|
+ { 0x00b3, 0x0000 },
|
|
+ { 0x2153, 0x0000 },
|
|
+ { 0x40f3, 0x0000 },
|
|
},
|
|
}, {
|
|
- 36000000, {
|
|
- { 0x00b3, 0x0000},
|
|
- { 0x2153, 0x0000},
|
|
- { 0x40f3, 0x0000}
|
|
+ 36800000, {
|
|
+ { 0x00b3, 0x0000 },
|
|
+ { 0x2153, 0x0000 },
|
|
+ { 0x40a2, 0x0001 },
|
|
},
|
|
}, {
|
|
- 40000000, {
|
|
- { 0x00b3, 0x0000},
|
|
- { 0x2153, 0x0000},
|
|
- { 0x40f3, 0x0000}
|
|
+ 46000000, {
|
|
+ { 0x00b3, 0x0000 },
|
|
+ { 0x2142, 0x0001 },
|
|
+ { 0x40a2, 0x0001 },
|
|
},
|
|
}, {
|
|
- 54000000, {
|
|
- { 0x0072, 0x0001},
|
|
- { 0x2142, 0x0001},
|
|
- { 0x40a2, 0x0001},
|
|
+ 61333000, {
|
|
+ { 0x0072, 0x0001 },
|
|
+ { 0x2142, 0x0001 },
|
|
+ { 0x40a2, 0x0001 },
|
|
},
|
|
}, {
|
|
- 65000000, {
|
|
- { 0x0072, 0x0001},
|
|
- { 0x2142, 0x0001},
|
|
- { 0x40a2, 0x0001},
|
|
+ 73600000, {
|
|
+ { 0x0072, 0x0001 },
|
|
+ { 0x2142, 0x0001 },
|
|
+ { 0x4061, 0x0002 },
|
|
},
|
|
}, {
|
|
- 66000000, {
|
|
- { 0x013e, 0x0003},
|
|
- { 0x217e, 0x0002},
|
|
- { 0x4061, 0x0002}
|
|
+ 92000000, {
|
|
+ { 0x0072, 0x0001 },
|
|
+ { 0x2145, 0x0002 },
|
|
+ { 0x4061, 0x0002 },
|
|
},
|
|
}, {
|
|
- 74250000, {
|
|
- { 0x0072, 0x0001},
|
|
- { 0x2145, 0x0002},
|
|
- { 0x4061, 0x0002}
|
|
+ 122666000, {
|
|
+ { 0x0051, 0x0002 },
|
|
+ { 0x2145, 0x0002 },
|
|
+ { 0x4061, 0x0002 },
|
|
},
|
|
}, {
|
|
- 83500000, {
|
|
- { 0x0072, 0x0001},
|
|
+ 147200000, {
|
|
+ { 0x0051, 0x0002 },
|
|
+ { 0x2145, 0x0002 },
|
|
+ { 0x4064, 0x0003 },
|
|
},
|
|
}, {
|
|
- 108000000, {
|
|
- { 0x0051, 0x0002},
|
|
- { 0x2145, 0x0002},
|
|
- { 0x4061, 0x0002}
|
|
+ 184000000, {
|
|
+ { 0x0051, 0x0002 },
|
|
+ { 0x214c, 0x0003 },
|
|
+ { 0x4064, 0x0003 },
|
|
},
|
|
}, {
|
|
- 106500000, {
|
|
- { 0x0051, 0x0002},
|
|
- { 0x2145, 0x0002},
|
|
- { 0x4061, 0x0002}
|
|
- },
|
|
- }, {
|
|
- 146250000, {
|
|
- { 0x0051, 0x0002},
|
|
- { 0x2145, 0x0002},
|
|
- { 0x4061, 0x0002}
|
|
+ 226666000, {
|
|
+ { 0x0040, 0x0003 },
|
|
+ { 0x214c, 0x0003 },
|
|
+ { 0x4064, 0x0003 },
|
|
},
|
|
}, {
|
|
- 148500000, {
|
|
- { 0x0051, 0x0003},
|
|
- { 0x214c, 0x0003},
|
|
- { 0x4064, 0x0003}
|
|
+ 272000000, {
|
|
+ { 0x0040, 0x0003 },
|
|
+ { 0x214c, 0x0003 },
|
|
+ { 0x5a64, 0x0003 },
|
|
},
|
|
}, {
|
|
340000000, {
|
|
@@ -166,11 +162,17 @@ static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = {
|
|
{ 0x3b4c, 0x0003 },
|
|
{ 0x5a64, 0x0003 },
|
|
},
|
|
+ }, {
|
|
+ 600000000, {
|
|
+ { 0x1a40, 0x0003 },
|
|
+ { 0x3b4c, 0x0003 },
|
|
+ { 0x5a64, 0x0003 },
|
|
+ },
|
|
}, {
|
|
~0UL, {
|
|
- { 0x00a0, 0x000a },
|
|
- { 0x2001, 0x000f },
|
|
- { 0x4002, 0x000f },
|
|
+ { 0x0000, 0x0000 },
|
|
+ { 0x0000, 0x0000 },
|
|
+ { 0x0000, 0x0000 },
|
|
},
|
|
}
|
|
};
|
|
@@ -178,23 +180,9 @@ static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = {
|
|
static const struct dw_hdmi_curr_ctrl rockchip_cur_ctr[] = {
|
|
/* pixelclk bpp8 bpp10 bpp12 */
|
|
{
|
|
- 40000000, { 0x0018, 0x0018, 0x0018 },
|
|
- }, {
|
|
- 65000000, { 0x0028, 0x0028, 0x0028 },
|
|
- }, {
|
|
- 66000000, { 0x0038, 0x0038, 0x0038 },
|
|
- }, {
|
|
- 74250000, { 0x0028, 0x0038, 0x0038 },
|
|
- }, {
|
|
- 83500000, { 0x0028, 0x0038, 0x0038 },
|
|
- }, {
|
|
- 146250000, { 0x0038, 0x0038, 0x0038 },
|
|
- }, {
|
|
- 148500000, { 0x0000, 0x0038, 0x0038 },
|
|
- }, {
|
|
600000000, { 0x0000, 0x0000, 0x0000 },
|
|
}, {
|
|
- ~0UL, { 0x0000, 0x0000, 0x0000},
|
|
+ ~0UL, { 0x0000, 0x0000, 0x0000 },
|
|
}
|
|
};
|
|
|
|
@@ -203,6 +191,7 @@ static const struct dw_hdmi_phy_config rockchip_phy_config[] = {
|
|
{ 74250000, 0x8009, 0x0004, 0x0272},
|
|
{ 148500000, 0x802b, 0x0004, 0x028d},
|
|
{ 297000000, 0x8039, 0x0005, 0x028d},
|
|
+ { 594000000, 0x8039, 0x0000, 0x019d},
|
|
{ ~0UL, 0x0000, 0x0000, 0x0000}
|
|
};
|
|
|
|
@@ -502,7 +491,7 @@ static struct rockchip_hdmi_chip_data rk3399_chip_data = {
|
|
.lcdsel_grf_reg = RK3399_GRF_SOC_CON20,
|
|
.lcdsel_big = HIWORD_UPDATE(0, RK3399_HDMI_LCDC_SEL),
|
|
.lcdsel_lit = HIWORD_UPDATE(RK3399_HDMI_LCDC_SEL, RK3399_HDMI_LCDC_SEL),
|
|
- .max_tmds_clock = 340000,
|
|
+ .max_tmds_clock = 594000,
|
|
};
|
|
|
|
static const struct dw_hdmi_plat_data rk3399_hdmi_drv_data = {
|
|
@@ -516,7 +505,7 @@ static const struct dw_hdmi_plat_data rk3399_hdmi_drv_data = {
|
|
|
|
static struct rockchip_hdmi_chip_data rk3568_chip_data = {
|
|
.lcdsel_grf_reg = -1,
|
|
- .max_tmds_clock = 340000,
|
|
+ .max_tmds_clock = 594000,
|
|
};
|
|
|
|
static const struct dw_hdmi_plat_data rk3568_hdmi_drv_data = {
|
|
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
|
|
new file mode 100644
|
|
index 0000000000000..9c796ee4c303a
|
|
--- /dev/null
|
|
+++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
|
|
@@ -0,0 +1,424 @@
|
|
+// SPDX-License-Identifier: GPL-2.0-or-later
|
|
+/*
|
|
+ * Copyright (c) 2021-2022 Rockchip Electronics Co., Ltd.
|
|
+ * Copyright (c) 2024 Collabora Ltd.
|
|
+ *
|
|
+ * Author: Algea Cao <algea.cao@rock-chips.com>
|
|
+ * Author: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
|
+ */
|
|
+
|
|
+#include <linux/clk.h>
|
|
+#include <linux/gpio/consumer.h>
|
|
+#include <linux/mfd/syscon.h>
|
|
+#include <linux/module.h>
|
|
+#include <linux/platform_device.h>
|
|
+#include <linux/phy/phy.h>
|
|
+#include <linux/regmap.h>
|
|
+#include <linux/workqueue.h>
|
|
+
|
|
+#include <drm/bridge/dw_hdmi_qp.h>
|
|
+#include <drm/display/drm_hdmi_helper.h>
|
|
+#include <drm/drm_bridge_connector.h>
|
|
+#include <drm/drm_of.h>
|
|
+#include <drm/drm_probe_helper.h>
|
|
+#include <drm/drm_simple_kms_helper.h>
|
|
+
|
|
+#include "rockchip_drm_drv.h"
|
|
+
|
|
+#define RK3588_GRF_SOC_CON2 0x0308
|
|
+#define RK3588_HDMI0_HPD_INT_MSK BIT(13)
|
|
+#define RK3588_HDMI0_HPD_INT_CLR BIT(12)
|
|
+#define RK3588_GRF_SOC_CON7 0x031c
|
|
+#define RK3588_SET_HPD_PATH_MASK GENMASK(13, 12)
|
|
+#define RK3588_GRF_SOC_STATUS1 0x0384
|
|
+#define RK3588_HDMI0_LEVEL_INT BIT(16)
|
|
+#define RK3588_GRF_VO1_CON3 0x000c
|
|
+#define RK3588_SCLIN_MASK BIT(9)
|
|
+#define RK3588_SDAIN_MASK BIT(10)
|
|
+#define RK3588_MODE_MASK BIT(11)
|
|
+#define RK3588_I2S_SEL_MASK BIT(13)
|
|
+#define RK3588_GRF_VO1_CON9 0x0024
|
|
+#define RK3588_HDMI0_GRANT_SEL BIT(10)
|
|
+
|
|
+#define HIWORD_UPDATE(val, mask) ((val) | (mask) << 16)
|
|
+#define HOTPLUG_DEBOUNCE_MS 150
|
|
+
|
|
+struct rockchip_hdmi_qp {
|
|
+ struct device *dev;
|
|
+ struct regmap *regmap;
|
|
+ struct regmap *vo_regmap;
|
|
+ struct rockchip_encoder encoder;
|
|
+ struct clk *ref_clk;
|
|
+ struct dw_hdmi_qp *hdmi;
|
|
+ struct phy *phy;
|
|
+ struct gpio_desc *enable_gpio;
|
|
+ struct delayed_work hpd_work;
|
|
+};
|
|
+
|
|
+static struct rockchip_hdmi_qp *to_rockchip_hdmi_qp(struct drm_encoder *encoder)
|
|
+{
|
|
+ struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
|
|
+
|
|
+ return container_of(rkencoder, struct rockchip_hdmi_qp, encoder);
|
|
+}
|
|
+
|
|
+static void dw_hdmi_qp_rockchip_encoder_enable(struct drm_encoder *encoder)
|
|
+{
|
|
+ struct rockchip_hdmi_qp *hdmi = to_rockchip_hdmi_qp(encoder);
|
|
+ struct drm_crtc *crtc = encoder->crtc;
|
|
+ unsigned long long rate;
|
|
+
|
|
+ /* Unconditionally switch to TMDS as FRL is not yet supported */
|
|
+ gpiod_set_value(hdmi->enable_gpio, 1);
|
|
+
|
|
+ if (crtc && crtc->state) {
|
|
+ rate = drm_hdmi_compute_mode_clock(&crtc->state->adjusted_mode,
|
|
+ 8, HDMI_COLORSPACE_RGB);
|
|
+ clk_set_rate(hdmi->ref_clk, rate);
|
|
+ /*
|
|
+ * FIXME: Temporary workaround to pass pixel clock rate
|
|
+ * to the PHY driver until phy_configure_opts_hdmi
|
|
+ * becomes available in the PHY API. See also the related
|
|
+ * comment in rk_hdptx_phy_power_on() from
|
|
+ * drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
|
|
+ */
|
|
+ phy_set_bus_width(hdmi->phy, rate / 100);
|
|
+ }
|
|
+}
|
|
+
|
|
+static int
|
|
+dw_hdmi_qp_rockchip_encoder_atomic_check(struct drm_encoder *encoder,
|
|
+ struct drm_crtc_state *crtc_state,
|
|
+ struct drm_connector_state *conn_state)
|
|
+{
|
|
+ struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
|
|
+
|
|
+ s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
|
|
+ s->output_type = DRM_MODE_CONNECTOR_HDMIA;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static const struct
|
|
+drm_encoder_helper_funcs dw_hdmi_qp_rockchip_encoder_helper_funcs = {
|
|
+ .enable = dw_hdmi_qp_rockchip_encoder_enable,
|
|
+ .atomic_check = dw_hdmi_qp_rockchip_encoder_atomic_check,
|
|
+};
|
|
+
|
|
+static int dw_hdmi_qp_rk3588_phy_init(struct dw_hdmi_qp *dw_hdmi, void *data)
|
|
+{
|
|
+ struct rockchip_hdmi_qp *hdmi = (struct rockchip_hdmi_qp *)data;
|
|
+
|
|
+ return phy_power_on(hdmi->phy);
|
|
+}
|
|
+
|
|
+static void dw_hdmi_qp_rk3588_phy_disable(struct dw_hdmi_qp *dw_hdmi,
|
|
+ void *data)
|
|
+{
|
|
+ struct rockchip_hdmi_qp *hdmi = (struct rockchip_hdmi_qp *)data;
|
|
+
|
|
+ phy_power_off(hdmi->phy);
|
|
+}
|
|
+
|
|
+static enum drm_connector_status
|
|
+dw_hdmi_qp_rk3588_read_hpd(struct dw_hdmi_qp *dw_hdmi, void *data)
|
|
+{
|
|
+ struct rockchip_hdmi_qp *hdmi = (struct rockchip_hdmi_qp *)data;
|
|
+ u32 val;
|
|
+
|
|
+ regmap_read(hdmi->regmap, RK3588_GRF_SOC_STATUS1, &val);
|
|
+
|
|
+ return val & RK3588_HDMI0_LEVEL_INT ?
|
|
+ connector_status_connected : connector_status_disconnected;
|
|
+}
|
|
+
|
|
+static void dw_hdmi_qp_rk3588_setup_hpd(struct dw_hdmi_qp *dw_hdmi, void *data)
|
|
+{
|
|
+ struct rockchip_hdmi_qp *hdmi = (struct rockchip_hdmi_qp *)data;
|
|
+
|
|
+ regmap_write(hdmi->regmap,
|
|
+ RK3588_GRF_SOC_CON2,
|
|
+ HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_CLR,
|
|
+ RK3588_HDMI0_HPD_INT_CLR |
|
|
+ RK3588_HDMI0_HPD_INT_MSK));
|
|
+}
|
|
+
|
|
+static const struct dw_hdmi_qp_phy_ops rk3588_hdmi_phy_ops = {
|
|
+ .init = dw_hdmi_qp_rk3588_phy_init,
|
|
+ .disable = dw_hdmi_qp_rk3588_phy_disable,
|
|
+ .read_hpd = dw_hdmi_qp_rk3588_read_hpd,
|
|
+ .setup_hpd = dw_hdmi_qp_rk3588_setup_hpd,
|
|
+};
|
|
+
|
|
+static void dw_hdmi_qp_rk3588_hpd_work(struct work_struct *work)
|
|
+{
|
|
+ struct rockchip_hdmi_qp *hdmi = container_of(work,
|
|
+ struct rockchip_hdmi_qp,
|
|
+ hpd_work.work);
|
|
+ struct drm_device *drm = hdmi->encoder.encoder.dev;
|
|
+ bool changed;
|
|
+
|
|
+ if (drm) {
|
|
+ changed = drm_helper_hpd_irq_event(drm);
|
|
+ if (changed)
|
|
+ drm_dbg(hdmi, "connector status changed\n");
|
|
+ }
|
|
+}
|
|
+
|
|
+static irqreturn_t dw_hdmi_qp_rk3588_hardirq(int irq, void *dev_id)
|
|
+{
|
|
+ struct rockchip_hdmi_qp *hdmi = dev_id;
|
|
+ u32 intr_stat, val;
|
|
+
|
|
+ regmap_read(hdmi->regmap, RK3588_GRF_SOC_STATUS1, &intr_stat);
|
|
+
|
|
+ if (intr_stat) {
|
|
+ val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_MSK,
|
|
+ RK3588_HDMI0_HPD_INT_MSK);
|
|
+ regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val);
|
|
+ return IRQ_WAKE_THREAD;
|
|
+ }
|
|
+
|
|
+ return IRQ_NONE;
|
|
+}
|
|
+
|
|
+static irqreturn_t dw_hdmi_qp_rk3588_irq(int irq, void *dev_id)
|
|
+{
|
|
+ struct rockchip_hdmi_qp *hdmi = dev_id;
|
|
+ u32 intr_stat, val;
|
|
+
|
|
+ regmap_read(hdmi->regmap, RK3588_GRF_SOC_STATUS1, &intr_stat);
|
|
+ if (!intr_stat)
|
|
+ return IRQ_NONE;
|
|
+
|
|
+ val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_CLR,
|
|
+ RK3588_HDMI0_HPD_INT_CLR);
|
|
+ regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val);
|
|
+
|
|
+ mod_delayed_work(system_wq, &hdmi->hpd_work,
|
|
+ msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
|
|
+
|
|
+ val |= HIWORD_UPDATE(0, RK3588_HDMI0_HPD_INT_MSK);
|
|
+ regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val);
|
|
+
|
|
+ return IRQ_HANDLED;
|
|
+}
|
|
+
|
|
+static const struct of_device_id dw_hdmi_qp_rockchip_dt_ids[] = {
|
|
+ { .compatible = "rockchip,rk3588-dw-hdmi-qp",
|
|
+ .data = &rk3588_hdmi_phy_ops },
|
|
+ {},
|
|
+};
|
|
+MODULE_DEVICE_TABLE(of, dw_hdmi_qp_rockchip_dt_ids);
|
|
+
|
|
+static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master,
|
|
+ void *data)
|
|
+{
|
|
+ static const char * const clk_names[] = {
|
|
+ "pclk", "earc", "aud", "hdp", "hclk_vo1",
|
|
+ "ref" /* keep "ref" last */
|
|
+ };
|
|
+ struct platform_device *pdev = to_platform_device(dev);
|
|
+ struct dw_hdmi_qp_plat_data plat_data;
|
|
+ struct drm_device *drm = data;
|
|
+ struct drm_connector *connector;
|
|
+ struct drm_encoder *encoder;
|
|
+ struct rockchip_hdmi_qp *hdmi;
|
|
+ struct clk *clk;
|
|
+ int ret, irq, i;
|
|
+ u32 val;
|
|
+
|
|
+ if (!pdev->dev.of_node)
|
|
+ return -ENODEV;
|
|
+
|
|
+ hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
|
|
+ if (!hdmi)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ plat_data.phy_ops = of_device_get_match_data(dev);
|
|
+ if (!plat_data.phy_ops)
|
|
+ return -ENODEV;
|
|
+
|
|
+ plat_data.phy_data = hdmi;
|
|
+ hdmi->dev = &pdev->dev;
|
|
+
|
|
+ encoder = &hdmi->encoder.encoder;
|
|
+ encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
|
|
+
|
|
+ rockchip_drm_encoder_set_crtc_endpoint_id(&hdmi->encoder,
|
|
+ dev->of_node, 0, 0);
|
|
+ /*
|
|
+ * If we failed to find the CRTC(s) which this encoder is
|
|
+ * supposed to be connected to, it's because the CRTC has
|
|
+ * not been registered yet. Defer probing, and hope that
|
|
+ * the required CRTC is added later.
|
|
+ */
|
|
+ if (encoder->possible_crtcs == 0)
|
|
+ return -EPROBE_DEFER;
|
|
+
|
|
+ hdmi->regmap = syscon_regmap_lookup_by_phandle(dev->of_node,
|
|
+ "rockchip,grf");
|
|
+ if (IS_ERR(hdmi->regmap)) {
|
|
+ drm_err(hdmi, "Unable to get rockchip,grf\n");
|
|
+ return PTR_ERR(hdmi->regmap);
|
|
+ }
|
|
+
|
|
+ hdmi->vo_regmap = syscon_regmap_lookup_by_phandle(dev->of_node,
|
|
+ "rockchip,vo-grf");
|
|
+ if (IS_ERR(hdmi->vo_regmap)) {
|
|
+ drm_err(hdmi, "Unable to get rockchip,vo-grf\n");
|
|
+ return PTR_ERR(hdmi->vo_regmap);
|
|
+ }
|
|
+
|
|
+ for (i = 0; i < ARRAY_SIZE(clk_names); i++) {
|
|
+ clk = devm_clk_get_enabled(hdmi->dev, clk_names[i]);
|
|
+
|
|
+ if (IS_ERR(clk)) {
|
|
+ ret = PTR_ERR(clk);
|
|
+ if (ret != -EPROBE_DEFER)
|
|
+ drm_err(hdmi, "Failed to get %s clock: %d\n",
|
|
+ clk_names[i], ret);
|
|
+ return ret;
|
|
+ }
|
|
+ }
|
|
+ hdmi->ref_clk = clk;
|
|
+
|
|
+ hdmi->enable_gpio = devm_gpiod_get_optional(hdmi->dev, "enable",
|
|
+ GPIOD_OUT_HIGH);
|
|
+ if (IS_ERR(hdmi->enable_gpio)) {
|
|
+ ret = PTR_ERR(hdmi->enable_gpio);
|
|
+ drm_err(hdmi, "Failed to request enable GPIO: %d\n", ret);
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ hdmi->phy = devm_of_phy_get_by_index(dev, dev->of_node, 0);
|
|
+ if (IS_ERR(hdmi->phy)) {
|
|
+ ret = PTR_ERR(hdmi->phy);
|
|
+ if (ret != -EPROBE_DEFER)
|
|
+ drm_err(hdmi, "failed to get phy: %d\n", ret);
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ val = HIWORD_UPDATE(RK3588_SCLIN_MASK, RK3588_SCLIN_MASK) |
|
|
+ HIWORD_UPDATE(RK3588_SDAIN_MASK, RK3588_SDAIN_MASK) |
|
|
+ HIWORD_UPDATE(RK3588_MODE_MASK, RK3588_MODE_MASK) |
|
|
+ HIWORD_UPDATE(RK3588_I2S_SEL_MASK, RK3588_I2S_SEL_MASK);
|
|
+ regmap_write(hdmi->vo_regmap, RK3588_GRF_VO1_CON3, val);
|
|
+
|
|
+ val = HIWORD_UPDATE(RK3588_SET_HPD_PATH_MASK,
|
|
+ RK3588_SET_HPD_PATH_MASK);
|
|
+ regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON7, val);
|
|
+
|
|
+ val = HIWORD_UPDATE(RK3588_HDMI0_GRANT_SEL,
|
|
+ RK3588_HDMI0_GRANT_SEL);
|
|
+ regmap_write(hdmi->vo_regmap, RK3588_GRF_VO1_CON9, val);
|
|
+
|
|
+ val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_MSK, RK3588_HDMI0_HPD_INT_MSK);
|
|
+ regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val);
|
|
+
|
|
+ INIT_DELAYED_WORK(&hdmi->hpd_work, dw_hdmi_qp_rk3588_hpd_work);
|
|
+
|
|
+ plat_data.main_irq = platform_get_irq_byname(pdev, "main");
|
|
+ if (plat_data.main_irq < 0)
|
|
+ return plat_data.main_irq;
|
|
+
|
|
+ irq = platform_get_irq_byname(pdev, "hpd");
|
|
+ if (irq < 0)
|
|
+ return irq;
|
|
+
|
|
+ ret = devm_request_threaded_irq(hdmi->dev, irq,
|
|
+ dw_hdmi_qp_rk3588_hardirq,
|
|
+ dw_hdmi_qp_rk3588_irq,
|
|
+ IRQF_SHARED, "dw-hdmi-qp-hpd",
|
|
+ hdmi);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ drm_encoder_helper_add(encoder, &dw_hdmi_qp_rockchip_encoder_helper_funcs);
|
|
+ drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
|
|
+
|
|
+ platform_set_drvdata(pdev, hdmi);
|
|
+
|
|
+ hdmi->hdmi = dw_hdmi_qp_bind(pdev, encoder, &plat_data);
|
|
+ if (IS_ERR(hdmi->hdmi)) {
|
|
+ ret = PTR_ERR(hdmi->hdmi);
|
|
+ drm_encoder_cleanup(encoder);
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ connector = drm_bridge_connector_init(drm, encoder);
|
|
+ if (IS_ERR(connector)) {
|
|
+ ret = PTR_ERR(connector);
|
|
+ drm_err(hdmi, "failed to init bridge connector: %d\n", ret);
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ return drm_connector_attach_encoder(connector, encoder);
|
|
+}
|
|
+
|
|
+static void dw_hdmi_qp_rockchip_unbind(struct device *dev,
|
|
+ struct device *master,
|
|
+ void *data)
|
|
+{
|
|
+ struct rockchip_hdmi_qp *hdmi = dev_get_drvdata(dev);
|
|
+
|
|
+ cancel_delayed_work_sync(&hdmi->hpd_work);
|
|
+
|
|
+ drm_encoder_cleanup(&hdmi->encoder.encoder);
|
|
+}
|
|
+
|
|
+static const struct component_ops dw_hdmi_qp_rockchip_ops = {
|
|
+ .bind = dw_hdmi_qp_rockchip_bind,
|
|
+ .unbind = dw_hdmi_qp_rockchip_unbind,
|
|
+};
|
|
+
|
|
+static int dw_hdmi_qp_rockchip_probe(struct platform_device *pdev)
|
|
+{
|
|
+ return component_add(&pdev->dev, &dw_hdmi_qp_rockchip_ops);
|
|
+}
|
|
+
|
|
+static void dw_hdmi_qp_rockchip_remove(struct platform_device *pdev)
|
|
+{
|
|
+ component_del(&pdev->dev, &dw_hdmi_qp_rockchip_ops);
|
|
+}
|
|
+
|
|
+static int __maybe_unused dw_hdmi_qp_rockchip_resume(struct device *dev)
|
|
+{
|
|
+ struct rockchip_hdmi_qp *hdmi = dev_get_drvdata(dev);
|
|
+ u32 val;
|
|
+
|
|
+ val = HIWORD_UPDATE(RK3588_SCLIN_MASK, RK3588_SCLIN_MASK) |
|
|
+ HIWORD_UPDATE(RK3588_SDAIN_MASK, RK3588_SDAIN_MASK) |
|
|
+ HIWORD_UPDATE(RK3588_MODE_MASK, RK3588_MODE_MASK) |
|
|
+ HIWORD_UPDATE(RK3588_I2S_SEL_MASK, RK3588_I2S_SEL_MASK);
|
|
+ regmap_write(hdmi->vo_regmap, RK3588_GRF_VO1_CON3, val);
|
|
+
|
|
+ val = HIWORD_UPDATE(RK3588_SET_HPD_PATH_MASK,
|
|
+ RK3588_SET_HPD_PATH_MASK);
|
|
+ regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON7, val);
|
|
+
|
|
+ val = HIWORD_UPDATE(RK3588_HDMI0_GRANT_SEL,
|
|
+ RK3588_HDMI0_GRANT_SEL);
|
|
+ regmap_write(hdmi->vo_regmap, RK3588_GRF_VO1_CON9, val);
|
|
+
|
|
+ dw_hdmi_qp_resume(dev, hdmi->hdmi);
|
|
+
|
|
+ if (hdmi->encoder.encoder.dev)
|
|
+ drm_helper_hpd_irq_event(hdmi->encoder.encoder.dev);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static const struct dev_pm_ops dw_hdmi_qp_rockchip_pm = {
|
|
+ SET_SYSTEM_SLEEP_PM_OPS(NULL, dw_hdmi_qp_rockchip_resume)
|
|
+};
|
|
+
|
|
+struct platform_driver dw_hdmi_qp_rockchip_pltfm_driver = {
|
|
+ .probe = dw_hdmi_qp_rockchip_probe,
|
|
+ .remove = dw_hdmi_qp_rockchip_remove,
|
|
+ .driver = {
|
|
+ .name = "dwhdmiqp-rockchip",
|
|
+ .pm = &dw_hdmi_qp_rockchip_pm,
|
|
+ .of_match_table = dw_hdmi_qp_rockchip_dt_ids,
|
|
+ },
|
|
+};
|
|
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
|
|
index 11e5d10de4d73..b81b0c4da4c6b 100644
|
|
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
|
|
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
|
|
@@ -358,11 +358,34 @@ static void rockchip_drm_match_remove(struct device *dev)
|
|
device_link_del(link);
|
|
}
|
|
|
|
+/* list of preferred vop devices */
|
|
+static const char *const rockchip_drm_match_preferred[] = {
|
|
+ "rockchip,rk3399-vop-big",
|
|
+ NULL,
|
|
+};
|
|
+
|
|
static struct component_match *rockchip_drm_match_add(struct device *dev)
|
|
{
|
|
struct component_match *match = NULL;
|
|
+ struct device_node *port;
|
|
int i;
|
|
|
|
+ /* add preferred vop device match before adding driver device matches */
|
|
+ for (i = 0; ; i++) {
|
|
+ port = of_parse_phandle(dev->of_node, "ports", i);
|
|
+ if (!port)
|
|
+ break;
|
|
+
|
|
+ if (of_device_is_available(port->parent) &&
|
|
+ of_device_compatible_match(port->parent,
|
|
+ rockchip_drm_match_preferred))
|
|
+ drm_of_component_match_add(dev, &match,
|
|
+ component_compare_of,
|
|
+ port->parent);
|
|
+
|
|
+ of_node_put(port);
|
|
+ }
|
|
+
|
|
for (i = 0; i < num_rockchip_sub_drivers; i++) {
|
|
struct platform_driver *drv = rockchip_sub_drivers[i];
|
|
struct device *p = NULL, *d;
|
|
@@ -507,6 +530,8 @@ static int __init rockchip_drm_init(void)
|
|
ADD_ROCKCHIP_SUB_DRIVER(cdn_dp_driver, CONFIG_ROCKCHIP_CDN_DP);
|
|
ADD_ROCKCHIP_SUB_DRIVER(dw_hdmi_rockchip_pltfm_driver,
|
|
CONFIG_ROCKCHIP_DW_HDMI);
|
|
+ ADD_ROCKCHIP_SUB_DRIVER(dw_hdmi_qp_rockchip_pltfm_driver,
|
|
+ CONFIG_ROCKCHIP_DW_HDMI_QP);
|
|
ADD_ROCKCHIP_SUB_DRIVER(dw_mipi_dsi_rockchip_driver,
|
|
CONFIG_ROCKCHIP_DW_MIPI_DSI);
|
|
ADD_ROCKCHIP_SUB_DRIVER(inno_hdmi_driver, CONFIG_ROCKCHIP_INNO_HDMI);
|
|
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
|
|
index 8d566fcd80a23..24b4ce5ceaf19 100644
|
|
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
|
|
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
|
|
@@ -88,6 +88,7 @@ int rockchip_drm_encoder_set_crtc_endpoint_id(struct rockchip_encoder *rencoder,
|
|
int rockchip_drm_endpoint_is_subdriver(struct device_node *ep);
|
|
extern struct platform_driver cdn_dp_driver;
|
|
extern struct platform_driver dw_hdmi_rockchip_pltfm_driver;
|
|
+extern struct platform_driver dw_hdmi_qp_rockchip_pltfm_driver;
|
|
extern struct platform_driver dw_mipi_dsi_rockchip_driver;
|
|
extern struct platform_driver inno_hdmi_driver;
|
|
extern struct platform_driver rockchip_dp_driver;
|
|
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/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
|
|
index 66d44a404ad0c..d4383c2d7d1a8 100644
|
|
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
|
|
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
|
|
@@ -10,6 +10,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>
|
|
@@ -2345,6 +2346,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 = {
|
|
@@ -2413,6 +2424,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 */
|
|
@@ -2439,6 +2455,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 2168b6cd71673..5d7cda175a0ce 100644
|
|
--- a/drivers/input/rmi4/rmi_driver.c
|
|
+++ b/drivers/input/rmi4/rmi_driver.c
|
|
@@ -182,34 +182,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;
|
|
}
|
|
@@ -217,7 +230,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;
|
|
|
|
@@ -235,8 +247,6 @@ static int rmi_irq_init(struct rmi_device *rmi_dev)
|
|
return ret;
|
|
}
|
|
|
|
- data->enabled = true;
|
|
-
|
|
return 0;
|
|
}
|
|
|
|
@@ -886,23 +896,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);
|
|
@@ -922,20 +936,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:
|
|
@@ -978,6 +994,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);
|
|
|
|
@@ -1223,9 +1241,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 83c8e617a2c58..27f9b45170954 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>
|
|
@@ -2932,6 +2933,27 @@ int iommu_dev_disable_feature(struct device *dev, enum iommu_dev_features feat)
|
|
}
|
|
EXPORT_SYMBOL_GPL(iommu_dev_disable_feature);
|
|
|
|
+#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/net/wireless/realtek/rtl8xxxu/core.c b/drivers/net/wireless/realtek/rtl8xxxu/core.c
|
|
index f95898f68d68a..4ce0c05c51291 100644
|
|
--- a/drivers/net/wireless/realtek/rtl8xxxu/core.c
|
|
+++ b/drivers/net/wireless/realtek/rtl8xxxu/core.c
|
|
@@ -8147,6 +8147,8 @@ static const struct usb_device_id dev_table[] = {
|
|
.driver_info = (unsigned long)&rtl8192cu_fops},
|
|
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x817e, 0xff, 0xff, 0xff),
|
|
.driver_info = (unsigned long)&rtl8192cu_fops},
|
|
+{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x8186, 0xff, 0xff, 0xff),
|
|
+ .driver_info = (unsigned long)&rtl8192cu_fops},
|
|
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x818a, 0xff, 0xff, 0xff),
|
|
.driver_info = (unsigned long)&rtl8192cu_fops},
|
|
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x317f, 0xff, 0xff, 0xff),
|
|
@@ -8157,12 +8159,18 @@ static const struct usb_device_id dev_table[] = {
|
|
.driver_info = (unsigned long)&rtl8192cu_fops},
|
|
{USB_DEVICE_AND_INTERFACE_INFO(0x050d, 0x1102, 0xff, 0xff, 0xff),
|
|
.driver_info = (unsigned long)&rtl8192cu_fops},
|
|
+{USB_DEVICE_AND_INTERFACE_INFO(0x050d, 0x11f2, 0xff, 0xff, 0xff),
|
|
+ .driver_info = (unsigned long)&rtl8192cu_fops},
|
|
{USB_DEVICE_AND_INTERFACE_INFO(0x06f8, 0xe033, 0xff, 0xff, 0xff),
|
|
.driver_info = (unsigned long)&rtl8192cu_fops},
|
|
+{USB_DEVICE_AND_INTERFACE_INFO(0x07b8, 0x8188, 0xff, 0xff, 0xff),
|
|
+ .driver_info = (unsigned long)&rtl8192cu_fops},
|
|
{USB_DEVICE_AND_INTERFACE_INFO(0x07b8, 0x8189, 0xff, 0xff, 0xff),
|
|
.driver_info = (unsigned long)&rtl8192cu_fops},
|
|
{USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9041, 0xff, 0xff, 0xff),
|
|
.driver_info = (unsigned long)&rtl8192cu_fops},
|
|
+{USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9043, 0xff, 0xff, 0xff),
|
|
+ .driver_info = (unsigned long)&rtl8192cu_fops},
|
|
{USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x17ba, 0xff, 0xff, 0xff),
|
|
.driver_info = (unsigned long)&rtl8192cu_fops},
|
|
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x1e1e, 0xff, 0xff, 0xff),
|
|
@@ -8179,6 +8187,10 @@ static const struct usb_device_id dev_table[] = {
|
|
.driver_info = (unsigned long)&rtl8192cu_fops},
|
|
{USB_DEVICE_AND_INTERFACE_INFO(0x13d3, 0x3357, 0xff, 0xff, 0xff),
|
|
.driver_info = (unsigned long)&rtl8192cu_fops},
|
|
+{USB_DEVICE_AND_INTERFACE_INFO(0x13d3, 0x3358, 0xff, 0xff, 0xff),
|
|
+ .driver_info = (unsigned long)&rtl8192cu_fops},
|
|
+{USB_DEVICE_AND_INTERFACE_INFO(0x13d3, 0x3359, 0xff, 0xff, 0xff),
|
|
+ .driver_info = (unsigned long)&rtl8192cu_fops},
|
|
{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x330b, 0xff, 0xff, 0xff),
|
|
.driver_info = (unsigned long)&rtl8192cu_fops},
|
|
{USB_DEVICE_AND_INTERFACE_INFO(0x2019, 0x4902, 0xff, 0xff, 0xff),
|
|
@@ -8193,6 +8205,8 @@ static const struct usb_device_id dev_table[] = {
|
|
.driver_info = (unsigned long)&rtl8192cu_fops},
|
|
{USB_DEVICE_AND_INTERFACE_INFO(0x4856, 0x0091, 0xff, 0xff, 0xff),
|
|
.driver_info = (unsigned long)&rtl8192cu_fops},
|
|
+{USB_DEVICE_AND_INTERFACE_INFO(0x9846, 0x9041, 0xff, 0xff, 0xff),
|
|
+ .driver_info = (unsigned long)&rtl8192cu_fops},
|
|
{USB_DEVICE_AND_INTERFACE_INFO(0xcdab, 0x8010, 0xff, 0xff, 0xff),
|
|
.driver_info = (unsigned long)&rtl8192cu_fops},
|
|
{USB_DEVICE_AND_INTERFACE_INFO(0x04f2, 0xaff7, 0xff, 0xff, 0xff),
|
|
@@ -8218,6 +8232,8 @@ static const struct usb_device_id dev_table[] = {
|
|
.driver_info = (unsigned long)&rtl8192cu_fops},
|
|
{USB_DEVICE_AND_INTERFACE_INFO(0x0586, 0x341f, 0xff, 0xff, 0xff),
|
|
.driver_info = (unsigned long)&rtl8192cu_fops},
|
|
+{USB_DEVICE_AND_INTERFACE_INFO(0x06f8, 0xe033, 0xff, 0xff, 0xff),
|
|
+ .driver_info = (unsigned long)&rtl8192cu_fops},
|
|
{USB_DEVICE_AND_INTERFACE_INFO(0x06f8, 0xe035, 0xff, 0xff, 0xff),
|
|
.driver_info = (unsigned long)&rtl8192cu_fops},
|
|
{USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x17ab, 0xff, 0xff, 0xff),
|
|
@@ -8226,6 +8242,8 @@ static const struct usb_device_id dev_table[] = {
|
|
.driver_info = (unsigned long)&rtl8192cu_fops},
|
|
{USB_DEVICE_AND_INTERFACE_INFO(0x0df6, 0x0070, 0xff, 0xff, 0xff),
|
|
.driver_info = (unsigned long)&rtl8192cu_fops},
|
|
+{USB_DEVICE_AND_INTERFACE_INFO(0x0df6, 0x0077, 0xff, 0xff, 0xff),
|
|
+ .driver_info = (unsigned long)&rtl8192cu_fops},
|
|
{USB_DEVICE_AND_INTERFACE_INFO(0x0789, 0x016d, 0xff, 0xff, 0xff),
|
|
.driver_info = (unsigned long)&rtl8192cu_fops},
|
|
{USB_DEVICE_AND_INTERFACE_INFO(0x07aa, 0x0056, 0xff, 0xff, 0xff),
|
|
@@ -8248,6 +8266,8 @@ static const struct usb_device_id dev_table[] = {
|
|
.driver_info = (unsigned long)&rtl8192cu_fops},
|
|
{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x330a, 0xff, 0xff, 0xff),
|
|
.driver_info = (unsigned long)&rtl8192cu_fops},
|
|
+{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x330d, 0xff, 0xff, 0xff),
|
|
+ .driver_info = (unsigned long)&rtl8192cu_fops},
|
|
{USB_DEVICE_AND_INTERFACE_INFO(0x2019, 0xab2b, 0xff, 0xff, 0xff),
|
|
.driver_info = (unsigned long)&rtl8192cu_fops},
|
|
{USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0x624d, 0xff, 0xff, 0xff),
|
|
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
|
|
index 8103bc24a54ea..ea629c78fa7c8 100644
|
|
--- a/drivers/pci/quirks.c
|
|
+++ b/drivers/pci/quirks.c
|
|
@@ -4452,6 +4452,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 ca4bc0ac76adc..8855e71076f48 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)
|
|
{
|
|
@@ -4377,6 +4385,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 4b93c0bd1d4bc..b98906237306d 100644
|
|
--- a/drivers/usb/core/hub.c
|
|
+++ b/drivers/usb/core/hub.c
|
|
@@ -5844,6 +5844,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/bridge/dw_hdmi_qp.h b/include/drm/bridge/dw_hdmi_qp.h
|
|
new file mode 100644
|
|
index 0000000000000..e9be6d507ad9c
|
|
--- /dev/null
|
|
+++ b/include/drm/bridge/dw_hdmi_qp.h
|
|
@@ -0,0 +1,32 @@
|
|
+/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
+/*
|
|
+ * Copyright (c) 2021-2022 Rockchip Electronics Co., Ltd.
|
|
+ * Copyright (c) 2024 Collabora Ltd.
|
|
+ */
|
|
+
|
|
+#ifndef __DW_HDMI_QP__
|
|
+#define __DW_HDMI_QP__
|
|
+
|
|
+struct device;
|
|
+struct drm_encoder;
|
|
+struct dw_hdmi_qp;
|
|
+struct platform_device;
|
|
+
|
|
+struct dw_hdmi_qp_phy_ops {
|
|
+ int (*init)(struct dw_hdmi_qp *hdmi, void *data);
|
|
+ void (*disable)(struct dw_hdmi_qp *hdmi, void *data);
|
|
+ enum drm_connector_status (*read_hpd)(struct dw_hdmi_qp *hdmi, void *data);
|
|
+ void (*setup_hpd)(struct dw_hdmi_qp *hdmi, void *data);
|
|
+};
|
|
+
|
|
+struct dw_hdmi_qp_plat_data {
|
|
+ const struct dw_hdmi_qp_phy_ops *phy_ops;
|
|
+ void *phy_data;
|
|
+ int main_irq;
|
|
+};
|
|
+
|
|
+struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev,
|
|
+ struct drm_encoder *encoder,
|
|
+ const struct dw_hdmi_qp_plat_data *plat_data);
|
|
+void dw_hdmi_qp_resume(struct device *dev, struct dw_hdmi_qp *hdmi);
|
|
+#endif /* __DW_HDMI_QP__ */
|
|
diff --git a/include/linux/efi.h b/include/linux/efi.h
|
|
index e28d880660337..860227e207970 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 */
|
|
@@ -875,6 +877,14 @@ static inline int efi_range_is_wc(unsigned long start, unsigned long len)
|
|
#define EFI_MEM_ATTR 10 /* Did firmware publish an EFI_MEMORY_ATTRIBUTES table? */
|
|
#define EFI_MEM_NO_SOFT_RESERVE 11 /* Is the kernel configured to ignore soft reservations? */
|
|
#define EFI_PRESERVE_BS_REGIONS 12 /* Are EFI boot-services memory segments available? */
|
|
+#define EFI_SECURE_BOOT 13 /* 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
|
|
/*
|
|
@@ -886,6 +896,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)
|
|
@@ -907,6 +919,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;
|
|
@@ -921,6 +935,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
|
|
@@ -1136,13 +1151,6 @@ static inline bool efi_runtime_disabled(void) { return true; }
|
|
extern void efi_call_virt_check_flags(unsigned long flags, const void *caller);
|
|
extern unsigned long efi_call_virt_save_flags(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 9eca013aa5e1f..6f25ce6867a24 100644
|
|
--- a/include/linux/lsm_hook_defs.h
|
|
+++ b/include/linux/lsm_hook_defs.h
|
|
@@ -438,6 +438,8 @@ LSM_HOOK(int, 0, bpf_token_capable, const struct bpf_token *token, int cap)
|
|
#endif /* CONFIG_BPF_SYSCALL */
|
|
|
|
LSM_HOOK(int, 0, locked_down, enum lockdown_reason what)
|
|
+LSM_HOOK(int, 0, lock_kernel_down, const char *where, enum lockdown_reason level)
|
|
+
|
|
|
|
#ifdef CONFIG_PERF_EVENTS
|
|
LSM_HOOK(int, 0, perf_event_open, struct perf_event_attr *attr, int type)
|
|
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 2ec8f3014757c..7273b2b8b23b1 100644
|
|
--- a/include/linux/security.h
|
|
+++ b/include/linux/security.h
|
|
@@ -522,6 +522,7 @@ int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen);
|
|
int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen);
|
|
int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen);
|
|
int security_locked_down(enum lockdown_reason what);
|
|
+int security_lock_kernel_down(const char *where, enum lockdown_reason level);
|
|
int lsm_fill_user_ctx(struct lsm_ctx __user *uctx, u32 *uctx_len,
|
|
void *val, size_t val_len, u64 id, u64 flags);
|
|
int security_bdev_alloc(struct block_device *bdev);
|
|
@@ -1504,6 +1505,10 @@ static inline int security_locked_down(enum lockdown_reason what)
|
|
{
|
|
return 0;
|
|
}
|
|
+static inline int security_lock_kernel_down(const char *where, enum lockdown_reason level)
|
|
+{
|
|
+ return 0;
|
|
+}
|
|
static inline int lsm_fill_user_ctx(struct lsm_ctx __user *uctx,
|
|
u32 *uctx_len, void *val, size_t val_len,
|
|
u64 id, u64 flags)
|
|
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/tags.sh b/scripts/tags.sh
|
|
index 191e0461d6d5b..e6f418b3e948b 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 f2bdbd55aa2bc..ddf496f7fca5a 100644
|
|
--- a/security/lockdown/lockdown.c
|
|
+++ b/security/lockdown/lockdown.c
|
|
@@ -74,6 +74,7 @@ static int lockdown_is_locked_down(enum lockdown_reason what)
|
|
|
|
static struct security_hook_list lockdown_hooks[] __ro_after_init = {
|
|
LSM_HOOK_INIT(locked_down, lockdown_is_locked_down),
|
|
+ LSM_HOOK_INIT(lock_kernel_down, lock_kernel_down),
|
|
};
|
|
|
|
static const struct lsm_id lockdown_lsmid = {
|
|
diff --git a/security/security.c b/security/security.c
|
|
index c5981e558bc26..431202cd09c17 100644
|
|
--- a/security/security.c
|
|
+++ b/security/security.c
|
|
@@ -5769,6 +5769,18 @@ int security_locked_down(enum lockdown_reason what)
|
|
}
|
|
EXPORT_SYMBOL(security_locked_down);
|
|
|
|
+/**
|
|
+ * 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 call_int_hook(lock_kernel_down, where, level);
|
|
+}
|
|
+EXPORT_SYMBOL(security_lock_kernel_down);
|
|
+
|
|
/**
|
|
* security_bdev_alloc() - Allocate a block device LSM blob
|
|
* @bdev: block device
|
|
diff --git a/tools/tracing/rtla/src/utils.c b/tools/tracing/rtla/src/utils.c
|
|
index 0735fcb827ed7..6fae234aaf36c 100644
|
|
--- a/tools/tracing/rtla/src/utils.c
|
|
+++ b/tools/tracing/rtla/src/utils.c
|
|
@@ -211,24 +211,20 @@ long parse_ns_duration(char *val)
|
|
/*
|
|
* This is a set of helper functions to use SCHED_DEADLINE.
|
|
*/
|
|
-#ifdef __x86_64__
|
|
-# define __NR_sched_setattr 314
|
|
-# define __NR_sched_getattr 315
|
|
-#elif __i386__
|
|
-# define __NR_sched_setattr 351
|
|
-# define __NR_sched_getattr 352
|
|
-#elif __arm__
|
|
-# define __NR_sched_setattr 380
|
|
-# define __NR_sched_getattr 381
|
|
-#elif __aarch64__ || __riscv
|
|
-# define __NR_sched_setattr 274
|
|
-# define __NR_sched_getattr 275
|
|
-#elif __powerpc__
|
|
-# define __NR_sched_setattr 355
|
|
-# define __NR_sched_getattr 356
|
|
-#elif __s390x__
|
|
-# define __NR_sched_setattr 345
|
|
-# define __NR_sched_getattr 346
|
|
+#ifndef __NR_sched_setattr
|
|
+# ifdef __x86_64__
|
|
+# define __NR_sched_setattr 314
|
|
+# elif __i386__
|
|
+# define __NR_sched_setattr 351
|
|
+# elif __arm__
|
|
+# define __NR_sched_setattr 380
|
|
+# elif __aarch64__ || __riscv
|
|
+# define __NR_sched_setattr 274
|
|
+# elif __powerpc__
|
|
+# define __NR_sched_setattr 355
|
|
+# elif __s390x__
|
|
+# define __NR_sched_setattr 345
|
|
+# endif
|
|
#endif
|
|
|
|
#define SCHED_DEADLINE 6
|