From 93a9f06c4ce1e98ff76e37100ed10ed76a0d2273 Mon Sep 17 00:00:00 2001 From: lean Date: Sat, 27 Aug 2022 00:51:54 +0800 Subject: [PATCH] rockchip: backport rk3568 support to kernel 5.15 from immortalwrt --- target/linux/rockchip/Makefile | 2 +- target/linux/rockchip/armv8/config-5.15 | 16 + .../arch/arm64/boot/dts/rockchip/rk3566.dtsi | 35 + .../arch/arm64/boot/dts/rockchip/rk3568.dtsi | 143 + .../arch/arm64/boot/dts/rockchip/rk356x.dtsi | 1706 ++++ .../gpu/drm/rockchip/rockchip_drm_vop2.c | 2706 ++++++ .../gpu/drm/rockchip/rockchip_drm_vop2.h | 477 + .../gpu/drm/rockchip/rockchip_vop2_reg.c | 281 + .../rockchip/phy-rockchip-naneng-combphy.c | 581 ++ .../include/dt-bindings/soc/rockchip,vop2.h | 14 + .../boot/dts/rockchip/rk3328-nanopi-r2c.dts | 49 + .../rockchip/rk3328-orangepi-r1-plus-lts.dts | 66 + .../dts/rockchip/rk3328-orangepi-r1-plus.dts | 39 + .../boot/dts/rockchip/rk3568-nanopi-r5s.dts | 821 +- .../arm64/boot/dts/rockchip/rk3568-r66s.dts | 523 +- .../boot/dts/rockchip/rk3568-rock-3a.dts | 609 ++ .../boot/dts/rockchip/rk3568-station-p2.dts | 778 ++ .../files/drivers/phy/rockchip/p3phy.fw | 8192 ++++++++++++++++ .../phy/rockchip/phy-rockchip-snps-pcie3.c | 343 + .../rockchip/files/include/linux/phy/pcie.h | 12 + target/linux/rockchip/modules.mk | 2 + ...-rockchip-Add-support-for-rv1126-pdm.patch | 155 + ...kchip-pdm-Add-support-for-rk3568-pdm.patch | 26 + ...ockchip-pdm-Add-support-for-path-map.patch | 95 + ...-dts-rockchip-add-rk3568-tsadc-nodes.patch | 32 + ...hip_thermal-Allow-more-resets-for-ts.patch | 28 + ...ip-inno-usb2-support-address_cells-2.patch | 45 + ...p-inno-usb2-support-muxed-interrupts.patch | 237 + ...no-usb2-support-standalone-phy-nodes.patch | 44 + ...ockchip-inno-usb2-add-rk3568-support.patch | 104 + ...ckchip-Add-more-PLL-rates-for-rk3568.patch | 44 + ...SET_RATE_PARENT-to-the-HDMI-referenc.patch | 52 + ...port-setting-f_min-from-host-drivers.patch | 54 + ...chip-add-naneng-combo-phy-for-RK3568.patch | 49 + ...hip-Fix-handling-invalid-clock-rates.patch | 79 + ...c-rockchip-set-dwc3-clock-for-rk3566.patch | 51 + ...-Add-support-for-Hantro-G1-on-RK356x.patch | 71 + ...nno-usb2-Fix-muxed-interrupt-support.patch | 42 + ...-inno-usb2-Do-not-check-bvalid-twice.patch | 37 + ...b2-Do-not-lock-in-bvalid-IRQ-handler.patch | 31 + ...b2-Support-multi-bit-mask-properties.patch | 29 + ...chip-inno-usb2-Handle-bvalid-falling.patch | 58 + ...phy-rockchip-inno-usb2-Handle-ID-IRQ.patch | 230 + ...p-Mark-hclk_vo-as-critical-on-rk3568.patch | 66 + ...ed-drm_encoder-into-rockchip_decoder.patch | 601 ++ ...crtc_endpoint_id-to-rockchip_encoder.patch | 88 + ...rename-vpll-clock-to-reference-clock.patch | 93 + ...-rockchip-dw_hdmi-add-rk3568-support.patch | 84 + ...ckchip-dw_hdmi-add-regulator-support.patch | 109 + ...rm-rockchip-Make-VOP-driver-optional.patch | 65 + ...0-v5.19-drm-rockchip-Add-VOP2-driver.patch | 149 + ...kchip-dwc-Reset-core-at-driver-probe.patch | 72 + ...hip-dwc-Add-legacy-interrupt-support.patch | 163 + ...ockchip-vop2-unlock-on-error-path-in.patch | 27 + ...antro-Add-support-for-RK356x-encoder.patch | 96 + ...no-usb2-Ignore-OTG-IRQs-in-host-mode.patch | 36 + ...-Fix-RK3399-H.264-format-advertising.patch | 126 + ...sb2-Prevent-incorrect-error-on-probe.patch | 27 + ...hip-inno-usb2-Sync-initial-otg-state.patch | 33 + ...v6.0-arm64-enable-THP_SWAP-for-arm64.patch | 123 + .../108-phy-rockchip-Support-PCIe-v3.patch | 106 + ...ts-rockchip-rk3568-Add-PCIe-v3-nodes.patch | 174 + ...328-Add-support-for-OrangePi-R1-Plus.patch | 52 - ...Add-support-for-FriendlyARM-NanoPi-R.patch | 60 - ...Add-support-for-OrangePi-R1-Plus-LTS.patch | 94 - ...-support-for-FriendlyARM-NanoPi-Neo3.patch | 14 - ...ip-add-hardware-random-number-genera.patch | 19 + .../900-arm64-boot-add-dts-files.patch | 24 + .../0046-phy-rockchip-Support-PCIe-v3.patch | 335 - ...kchip-snps-pcie3-update-fw-when-init.patch | 8274 ----------------- 70 files changed, 21265 insertions(+), 8833 deletions(-) create mode 100644 target/linux/rockchip/files-5.15/arch/arm64/boot/dts/rockchip/rk3566.dtsi create mode 100644 target/linux/rockchip/files-5.15/arch/arm64/boot/dts/rockchip/rk3568.dtsi create mode 100644 target/linux/rockchip/files-5.15/arch/arm64/boot/dts/rockchip/rk356x.dtsi create mode 100644 target/linux/rockchip/files-5.15/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c create mode 100644 target/linux/rockchip/files-5.15/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h create mode 100644 target/linux/rockchip/files-5.15/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c create mode 100644 target/linux/rockchip/files-5.15/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c create mode 100644 target/linux/rockchip/files-5.15/include/dt-bindings/soc/rockchip,vop2.h create mode 100644 target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2c.dts create mode 100644 target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus-lts.dts create mode 100644 target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dts create mode 100644 target/linux/rockchip/files/drivers/phy/rockchip/p3phy.fw create mode 100644 target/linux/rockchip/files/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c create mode 100644 target/linux/rockchip/files/include/linux/phy/pcie.h create mode 100644 target/linux/rockchip/patches-5.15/008-0001-v5.16-ASoC-rockchip-Add-support-for-rv1126-pdm.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0002-v5.16-ASoC-rockchip-pdm-Add-support-for-rk3568-pdm.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0003-v5.16-ASoC-rockchip-pdm-Add-support-for-path-map.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0004-v5.16-arm64-dts-rockchip-add-rk3568-tsadc-nodes.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0005-v5.16-thermal-drivers-rockchip_thermal-Allow-more-resets-for-ts.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0006-v5.17-phy-phy-rockchip-inno-usb2-support-address_cells-2.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0007-v5.17-phy-phy-rockchip-inno-usb2-support-muxed-interrupts.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0008-v5.17-phy-phy-rockchip-inno-usb2-support-standalone-phy-nodes.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0009-v5.17-phy-phy-rockchip-inno-usb2-add-rk3568-support.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0010-v5.18-clk-rockchip-Add-more-PLL-rates-for-rk3568.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0011-v5.18-clk-rockchip-Add-CLK_SET_RATE_PARENT-to-the-HDMI-referenc.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0012-v5.18-mmc-dw_mmc-Support-setting-f_min-from-host-drivers.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0012-v5.18-phy-rockchip-add-naneng-combo-phy-for-RK3568.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0014-v5.18-mmc-dw-mmc-rockchip-Fix-handling-invalid-clock-rates.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0015-v5.19-soc-rockchip-set-dwc3-clock-for-rk3566.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0016-v5.19-media-hantro-Add-support-for-Hantro-G1-on-RK356x.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0017-v5.19-phy-rockchip-inno-usb2-Fix-muxed-interrupt-support.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0018-v5.19-phy-rockchip-inno-usb2-Do-not-check-bvalid-twice.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0019-v5.19-phy-rockchip-inno-usb2-Do-not-lock-in-bvalid-IRQ-handler.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0020-v5.19-phy-rockchip-inno-usb2-Support-multi-bit-mask-properties.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0021-v5.19-phy-rockchip-inno-usb2-Handle-bvalid-falling.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0022-v5.19-phy-rockchip-inno-usb2-Handle-ID-IRQ.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0023-v5.19-clk-rockchip-Mark-hclk_vo-as-critical-on-rk3568.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0024-v5.19-drm-rockchip-Embed-drm_encoder-into-rockchip_decoder.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0025-v5.19-drm-rockchip-Add-crtc_endpoint_id-to-rockchip_encoder.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0026-v5.19-drm-rockchip-dw_hdmi-rename-vpll-clock-to-reference-clock.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0027-v5.19-drm-rockchip-dw_hdmi-add-rk3568-support.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0028-v5.19-drm-rockchip-dw_hdmi-add-regulator-support.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0029-v5.19-drm-rockchip-Make-VOP-driver-optional.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0030-v5.19-drm-rockchip-Add-VOP2-driver.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0031-v5.19-PCI-rockchip-dwc-Reset-core-at-driver-probe.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0032-v5.19-PCI-rockchip-dwc-Add-legacy-interrupt-support.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0033-v6.0-drm-rockchip-vop2-unlock-on-error-path-in.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0034-v6.0-media-hantro-Add-support-for-RK356x-encoder.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0035-v6.0-phy-rockchip-inno-usb2-Ignore-OTG-IRQs-in-host-mode.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0036-v6.0-media-hantro-Fix-RK3399-H.264-format-advertising.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0037-v6.0-phy-rockchip-inno-usb2-Prevent-incorrect-error-on-probe.patch create mode 100644 target/linux/rockchip/patches-5.15/008-0038-v6.0-phy-rockchip-inno-usb2-Sync-initial-otg-state.patch create mode 100644 target/linux/rockchip/patches-5.15/009-v6.0-arm64-enable-THP_SWAP-for-arm64.patch create mode 100644 target/linux/rockchip/patches-5.15/108-phy-rockchip-Support-PCIe-v3.patch create mode 100644 target/linux/rockchip/patches-5.15/109-arm64-dts-rockchip-rk3568-Add-PCIe-v3-nodes.patch delete mode 100644 target/linux/rockchip/patches-5.15/202-rockchip-rk3328-Add-support-for-OrangePi-R1-Plus.patch delete mode 100644 target/linux/rockchip/patches-5.15/204-rockchip-rk3328-Add-support-for-FriendlyARM-NanoPi-R.patch delete mode 100644 target/linux/rockchip/patches-5.15/206-rockchip-rk3328-Add-support-for-OrangePi-R1-Plus-LTS.patch create mode 100644 target/linux/rockchip/patches-5.15/900-arm64-boot-add-dts-files.patch delete mode 100644 target/linux/rockchip/patches-5.19/0800-rockchip-snps-pcie3-update-fw-when-init.patch diff --git a/target/linux/rockchip/Makefile b/target/linux/rockchip/Makefile index e93c553f9..ffdf1a817 100644 --- a/target/linux/rockchip/Makefile +++ b/target/linux/rockchip/Makefile @@ -8,7 +8,7 @@ FEATURES:=ext4 audio usb usbgadget display gpio fpu pci pcie rootfs-part boot-pa SUBTARGETS:=armv8 KERNEL_PATCHVER=5.19 -KERNEL_TESTING_PATCHVER=5.4 +KERNEL_TESTING_PATCHVER=5.15 define Target/Description Build firmware image for Rockchip SoC devices. diff --git a/target/linux/rockchip/armv8/config-5.15 b/target/linux/rockchip/armv8/config-5.15 index c67df65ea..07739aaac 100644 --- a/target/linux/rockchip/armv8/config-5.15 +++ b/target/linux/rockchip/armv8/config-5.15 @@ -69,6 +69,14 @@ CONFIG_ARM_PSCI_CPUIDLE_DOMAIN=y CONFIG_ARM_PSCI_FW=y CONFIG_ARM_RK3328_DMC_DEVFREQ=y # CONFIG_ARM_RK3399_DMC_DEVFREQ is not set +CONFIG_ARM_SCMI_CPUFREQ=y +CONFIG_ARM_SCMI_HAVE_SHMEM=y +CONFIG_ARM_SCMI_HAVE_TRANSPORT=y +CONFIG_ARM_SCMI_POWER_DOMAIN=y +CONFIG_ARM_SCMI_PROTOCOL=y +CONFIG_ARM_SCMI_TRANSPORT_MAILBOX=y +CONFIG_ARM_SCMI_TRANSPORT_SMC=y +# CONFIG_ARM_SCMI_TRANSPORT_SMC_ATOMIC_ENABLE is not set CONFIG_ARM_SCPI_CPUFREQ=y CONFIG_ARM_SCPI_POWER_DOMAIN=y CONFIG_ARM_SCPI_PROTOCOL=y @@ -126,6 +134,7 @@ CONFIG_COMMON_CLK=y # CONFIG_COMMON_CLK_AXI_CLKGEN is not set CONFIG_COMMON_CLK_RK808=y CONFIG_COMMON_CLK_ROCKCHIP=y +CONFIG_COMMON_CLK_SCMI=y CONFIG_COMMON_CLK_SCPI=y CONFIG_COMPAT=y CONFIG_COMPAT_32BIT_TIME=y @@ -451,6 +460,8 @@ CONFIG_PCIEASPM_DEFAULT=y CONFIG_PCIEPORTBUS=y CONFIG_PCIE_DW=y CONFIG_PCIE_DW_HOST=y +CONFIG_PCIE_DW=y +CONFIG_PCIE_DW_HOST=y # CONFIG_PCIE_MICROCHIP_HOST is not set CONFIG_PCIE_PME=y CONFIG_PCIE_ROCKCHIP=y @@ -473,7 +484,9 @@ CONFIG_PHY_ROCKCHIP_EMMC=y # CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY is not set # CONFIG_PHY_ROCKCHIP_INNO_HDMI is not set CONFIG_PHY_ROCKCHIP_INNO_USB2=y +CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY=y CONFIG_PHY_ROCKCHIP_PCIE=y +CONFIG_PHY_ROCKCHIP_SNPS_PCIE3=y CONFIG_PHY_ROCKCHIP_TYPEC=y CONFIG_PHY_ROCKCHIP_USB=y CONFIG_PINCTRL=y @@ -528,6 +541,7 @@ CONFIG_REGMAP_I2C=y CONFIG_REGMAP_IRQ=y CONFIG_REGMAP_MMIO=y CONFIG_REGULATOR=y +# CONFIG_REGULATOR_ARM_SCMI is not set # CONFIG_REGULATOR_DA9121 is not set CONFIG_REGULATOR_FAN53555=y CONFIG_REGULATOR_FIXED_VOLTAGE=y @@ -538,6 +552,7 @@ CONFIG_REGULATOR_RK808=y # CONFIG_REGULATOR_RTQ6752 is not set CONFIG_RELOCATABLE=y CONFIG_RESET_CONTROLLER=y +CONFIG_RESET_SCMI=y CONFIG_RFS_ACCEL=y CONFIG_ROCKCHIP_EFUSE=y CONFIG_ROCKCHIP_GRF=y @@ -569,6 +584,7 @@ CONFIG_SCSI_SAS_LIBSAS=y # CONFIG_SECURITY_DMESG_RESTRICT is not set # CONFIG_SENSORS_AHT10 is not set # CONFIG_SENSORS_AQUACOMPUTER_D5NEXT is not set +# CONFIG_SENSORS_ARM_SCMI is not set CONFIG_SENSORS_ARM_SCPI=y # CONFIG_SENSORS_LTC2992 is not set # CONFIG_SENSORS_MAX127 is not set diff --git a/target/linux/rockchip/files-5.15/arch/arm64/boot/dts/rockchip/rk3566.dtsi b/target/linux/rockchip/files-5.15/arch/arm64/boot/dts/rockchip/rk3566.dtsi new file mode 100644 index 000000000..6c4b17d27 --- /dev/null +++ b/target/linux/rockchip/files-5.15/arch/arm64/boot/dts/rockchip/rk3566.dtsi @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +#include "rk356x.dtsi" + +/ { + compatible = "rockchip,rk3566"; +}; + +&pipegrf { + compatible = "rockchip,rk3566-pipe-grf", "syscon"; +}; + +&power { + power-domain@RK3568_PD_PIPE { + reg = ; + clocks = <&cru PCLK_PIPE>; + pm_qos = <&qos_pcie2x1>, + <&qos_sata1>, + <&qos_sata2>, + <&qos_usb3_0>, + <&qos_usb3_1>; + #power-domain-cells = <0>; + }; +}; + +&usb_host0_xhci { + phys = <&usb2phy0_otg>; + phy-names = "usb2-phy"; + extcon = <&usb2phy0>; + maximum-speed = "high-speed"; +}; + +&vop { + compatible = "rockchip,rk3566-vop"; +}; diff --git a/target/linux/rockchip/files-5.15/arch/arm64/boot/dts/rockchip/rk3568.dtsi b/target/linux/rockchip/files-5.15/arch/arm64/boot/dts/rockchip/rk3568.dtsi new file mode 100644 index 000000000..2bdf8c7e9 --- /dev/null +++ b/target/linux/rockchip/files-5.15/arch/arm64/boot/dts/rockchip/rk3568.dtsi @@ -0,0 +1,143 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2021 Rockchip Electronics Co., Ltd. + */ + +#include "rk356x.dtsi" + +/ { + compatible = "rockchip,rk3568"; + + sata0: sata@fc000000 { + compatible = "rockchip,rk3568-dwc-ahci", "snps,dwc-ahci"; + reg = <0 0xfc000000 0 0x1000>; + clocks = <&cru ACLK_SATA0>, <&cru CLK_SATA0_PMALIVE>, + <&cru CLK_SATA0_RXOOB>; + clock-names = "sata", "pmalive", "rxoob"; + interrupts = ; + phys = <&combphy0 PHY_TYPE_SATA>; + phy-names = "sata-phy"; + ports-implemented = <0x1>; + power-domains = <&power RK3568_PD_PIPE>; + status = "disabled"; + }; + + pipe_phy_grf0: syscon@fdc70000 { + compatible = "rockchip,rk3568-pipe-phy-grf", "syscon"; + reg = <0x0 0xfdc70000 0x0 0x1000>; + }; + + qos_pcie3x1: qos@fe190080 { + compatible = "rockchip,rk3568-qos", "syscon"; + reg = <0x0 0xfe190080 0x0 0x20>; + }; + + qos_pcie3x2: qos@fe190100 { + compatible = "rockchip,rk3568-qos", "syscon"; + reg = <0x0 0xfe190100 0x0 0x20>; + }; + + qos_sata0: qos@fe190200 { + compatible = "rockchip,rk3568-qos", "syscon"; + reg = <0x0 0xfe190200 0x0 0x20>; + }; + + gmac0: ethernet@fe2a0000 { + compatible = "rockchip,rk3568-gmac", "snps,dwmac-4.20a"; + reg = <0x0 0xfe2a0000 0x0 0x10000>; + interrupts = , + ; + interrupt-names = "macirq", "eth_wake_irq"; + clocks = <&cru SCLK_GMAC0>, <&cru SCLK_GMAC0_RX_TX>, + <&cru SCLK_GMAC0_RX_TX>, <&cru CLK_MAC0_REFOUT>, + <&cru ACLK_GMAC0>, <&cru PCLK_GMAC0>, + <&cru SCLK_GMAC0_RX_TX>, <&cru CLK_GMAC0_PTP_REF>; + clock-names = "stmmaceth", "mac_clk_rx", + "mac_clk_tx", "clk_mac_refout", + "aclk_mac", "pclk_mac", + "clk_mac_speed", "ptp_ref"; + resets = <&cru SRST_A_GMAC0>; + reset-names = "stmmaceth"; + rockchip,grf = <&grf>; + snps,axi-config = <&gmac0_stmmac_axi_setup>; + snps,mixed-burst; + snps,mtl-rx-config = <&gmac0_mtl_rx_setup>; + snps,mtl-tx-config = <&gmac0_mtl_tx_setup>; + snps,tso; + status = "disabled"; + + mdio0: mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <0x1>; + #size-cells = <0x0>; + }; + + gmac0_stmmac_axi_setup: stmmac-axi-config { + snps,blen = <0 0 0 0 16 8 4>; + snps,rd_osr_lmt = <8>; + snps,wr_osr_lmt = <4>; + }; + + gmac0_mtl_rx_setup: rx-queues-config { + snps,rx-queues-to-use = <1>; + queue0 {}; + }; + + gmac0_mtl_tx_setup: tx-queues-config { + snps,tx-queues-to-use = <1>; + queue0 {}; + }; + }; + + combphy0: phy@fe820000 { + compatible = "rockchip,rk3568-naneng-combphy"; + reg = <0x0 0xfe820000 0x0 0x100>; + clocks = <&pmucru CLK_PCIEPHY0_REF>, + <&cru PCLK_PIPEPHY0>, + <&cru PCLK_PIPE>; + clock-names = "ref", "apb", "pipe"; + assigned-clocks = <&pmucru CLK_PCIEPHY0_REF>; + assigned-clock-rates = <100000000>; + resets = <&cru SRST_PIPEPHY0>; + rockchip,pipe-grf = <&pipegrf>; + rockchip,pipe-phy-grf = <&pipe_phy_grf0>; + #phy-cells = <1>; + status = "disabled"; + }; +}; + +&cpu0_opp_table { + opp-1992000000 { + opp-hz = /bits/ 64 <1992000000>; + opp-microvolt = <1150000 1150000 1150000>; + }; +}; + +&pipegrf { + compatible = "rockchip,rk3568-pipe-grf", "syscon"; +}; + +&power { + power-domain@RK3568_PD_PIPE { + reg = ; + clocks = <&cru PCLK_PIPE>; + pm_qos = <&qos_pcie2x1>, + <&qos_pcie3x1>, + <&qos_pcie3x2>, + <&qos_sata0>, + <&qos_sata1>, + <&qos_sata2>, + <&qos_usb3_0>, + <&qos_usb3_1>; + #power-domain-cells = <0>; + }; +}; + +&usb_host0_xhci { + phys = <&usb2phy0_otg>, <&combphy0 PHY_TYPE_USB3>; + phy-names = "usb2-phy", "usb3-phy"; +}; + +&vop { + compatible = "rockchip,rk3568-vop"; +}; diff --git a/target/linux/rockchip/files-5.15/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/target/linux/rockchip/files-5.15/arch/arm64/boot/dts/rockchip/rk356x.dtsi new file mode 100644 index 000000000..319981c3e --- /dev/null +++ b/target/linux/rockchip/files-5.15/arch/arm64/boot/dts/rockchip/rk356x.dtsi @@ -0,0 +1,1706 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2021 Rockchip Electronics Co., Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/ { + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + aliases { + gpio0 = &gpio0; + gpio1 = &gpio1; + gpio2 = &gpio2; + gpio3 = &gpio3; + gpio4 = &gpio4; + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + i2c3 = &i2c3; + i2c4 = &i2c4; + i2c5 = &i2c5; + serial0 = &uart0; + serial1 = &uart1; + serial2 = &uart2; + serial3 = &uart3; + serial4 = &uart4; + serial5 = &uart5; + serial6 = &uart6; + serial7 = &uart7; + serial8 = &uart8; + serial9 = &uart9; + spi0 = &spi0; + spi1 = &spi1; + spi2 = &spi2; + spi3 = &spi3; + }; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a55"; + reg = <0x0 0x0>; + clocks = <&scmi_clk 0>; + #cooling-cells = <2>; + enable-method = "psci"; + operating-points-v2 = <&cpu0_opp_table>; + }; + + cpu1: cpu@100 { + device_type = "cpu"; + compatible = "arm,cortex-a55"; + reg = <0x0 0x100>; + #cooling-cells = <2>; + enable-method = "psci"; + operating-points-v2 = <&cpu0_opp_table>; + }; + + cpu2: cpu@200 { + device_type = "cpu"; + compatible = "arm,cortex-a55"; + reg = <0x0 0x200>; + #cooling-cells = <2>; + enable-method = "psci"; + operating-points-v2 = <&cpu0_opp_table>; + }; + + cpu3: cpu@300 { + device_type = "cpu"; + compatible = "arm,cortex-a55"; + reg = <0x0 0x300>; + #cooling-cells = <2>; + enable-method = "psci"; + operating-points-v2 = <&cpu0_opp_table>; + }; + }; + + cpu0_opp_table: opp-table-0 { + compatible = "operating-points-v2"; + opp-shared; + + opp-408000000 { + opp-hz = /bits/ 64 <408000000>; + opp-microvolt = <900000 900000 1150000>; + clock-latency-ns = <40000>; + }; + + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <900000 900000 1150000>; + }; + + opp-816000000 { + opp-hz = /bits/ 64 <816000000>; + opp-microvolt = <900000 900000 1150000>; + opp-suspend; + }; + + opp-1104000000 { + opp-hz = /bits/ 64 <1104000000>; + opp-microvolt = <900000 900000 1150000>; + }; + + opp-1416000000 { + opp-hz = /bits/ 64 <1416000000>; + opp-microvolt = <900000 900000 1150000>; + }; + + opp-1608000000 { + opp-hz = /bits/ 64 <1608000000>; + opp-microvolt = <975000 975000 1150000>; + }; + + opp-1800000000 { + opp-hz = /bits/ 64 <1800000000>; + opp-microvolt = <1050000 1050000 1150000>; + }; + }; + + display_subsystem: display-subsystem { + compatible = "rockchip,display-subsystem"; + ports = <&vop_out>; + }; + + firmware { + scmi: scmi { + compatible = "arm,scmi-smc"; + arm,smc-id = <0x82000010>; + shmem = <&scmi_shmem>; + #address-cells = <1>; + #size-cells = <0>; + + scmi_clk: protocol@14 { + reg = <0x14>; + #clock-cells = <1>; + }; + }; + }; + + gpu_opp_table: opp-table-1 { + compatible = "operating-points-v2"; + + opp-200000000 { + opp-hz = /bits/ 64 <200000000>; + opp-microvolt = <825000>; + }; + + opp-300000000 { + opp-hz = /bits/ 64 <300000000>; + opp-microvolt = <825000>; + }; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + opp-microvolt = <825000>; + }; + + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <825000>; + }; + + opp-700000000 { + opp-hz = /bits/ 64 <700000000>; + opp-microvolt = <900000>; + }; + + opp-800000000 { + opp-hz = /bits/ 64 <800000000>; + opp-microvolt = <1000000>; + }; + }; + + hdmi_sound: hdmi-sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "HDMI"; + simple-audio-card,format = "i2s"; + simple-audio-card,mclk-fs = <256>; + status = "disabled"; + + simple-audio-card,codec { + sound-dai = <&hdmi>; + }; + + simple-audio-card,cpu { + sound-dai = <&i2s0_8ch>; + }; + }; + + pmu { + compatible = "arm,cortex-a55-pmu"; + interrupts = , + , + , + ; + interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = , + , + , + ; + arm,no-tick-in-suspend; + }; + + xin24m: xin24m { + compatible = "fixed-clock"; + clock-frequency = <24000000>; + clock-output-names = "xin24m"; + #clock-cells = <0>; + }; + + xin32k: xin32k { + compatible = "fixed-clock"; + clock-frequency = <32768>; + clock-output-names = "xin32k"; + pinctrl-0 = <&clk32k_out0>; + pinctrl-names = "default"; + #clock-cells = <0>; + }; + + sram@10f000 { + compatible = "mmio-sram"; + reg = <0x0 0x0010f000 0x0 0x100>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x0 0x0010f000 0x100>; + + scmi_shmem: sram@0 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0x100>; + }; + }; + + sata1: sata@fc400000 { + compatible = "rockchip,rk3568-dwc-ahci", "snps,dwc-ahci"; + reg = <0 0xfc400000 0 0x1000>; + clocks = <&cru ACLK_SATA1>, <&cru CLK_SATA1_PMALIVE>, + <&cru CLK_SATA1_RXOOB>; + clock-names = "sata", "pmalive", "rxoob"; + interrupts = ; + phys = <&combphy1 PHY_TYPE_SATA>; + phy-names = "sata-phy"; + ports-implemented = <0x1>; + power-domains = <&power RK3568_PD_PIPE>; + status = "disabled"; + }; + + sata2: sata@fc800000 { + compatible = "rockchip,rk3568-dwc-ahci", "snps,dwc-ahci"; + reg = <0 0xfc800000 0 0x1000>; + clocks = <&cru ACLK_SATA2>, <&cru CLK_SATA2_PMALIVE>, + <&cru CLK_SATA2_RXOOB>; + clock-names = "sata", "pmalive", "rxoob"; + interrupts = ; + phys = <&combphy2 PHY_TYPE_SATA>; + phy-names = "sata-phy"; + ports-implemented = <0x1>; + power-domains = <&power RK3568_PD_PIPE>; + status = "disabled"; + }; + + usb_host0_xhci: usb@fcc00000 { + compatible = "rockchip,rk3568-dwc3", "snps,dwc3"; + reg = <0x0 0xfcc00000 0x0 0x400000>; + interrupts = ; + clocks = <&cru CLK_USB3OTG0_REF>, <&cru CLK_USB3OTG0_SUSPEND>, + <&cru ACLK_USB3OTG0>; + clock-names = "ref_clk", "suspend_clk", + "bus_clk"; + dr_mode = "otg"; + phy_type = "utmi_wide"; + power-domains = <&power RK3568_PD_PIPE>; + resets = <&cru SRST_USB3OTG0>; + snps,dis_u2_susphy_quirk; + status = "disabled"; + }; + + usb_host1_xhci: usb@fd000000 { + compatible = "rockchip,rk3568-dwc3", "snps,dwc3"; + reg = <0x0 0xfd000000 0x0 0x400000>; + interrupts = ; + clocks = <&cru CLK_USB3OTG1_REF>, <&cru CLK_USB3OTG1_SUSPEND>, + <&cru ACLK_USB3OTG1>; + clock-names = "ref_clk", "suspend_clk", + "bus_clk"; + dr_mode = "host"; + phys = <&usb2phy0_host>, <&combphy1 PHY_TYPE_USB3>; + phy-names = "usb2-phy", "usb3-phy"; + phy_type = "utmi_wide"; + power-domains = <&power RK3568_PD_PIPE>; + resets = <&cru SRST_USB3OTG1>; + snps,dis_u2_susphy_quirk; + status = "disabled"; + }; + + gic: interrupt-controller@fd400000 { + compatible = "arm,gic-v3"; + reg = <0x0 0xfd400000 0 0x10000>, /* GICD */ + <0x0 0xfd460000 0 0x80000>; /* GICR */ + interrupts = ; + interrupt-controller; + #interrupt-cells = <3>; + mbi-alias = <0x0 0xfd410000>; + mbi-ranges = <296 24>; + msi-controller; + }; + + usb_host0_ehci: usb@fd800000 { + compatible = "generic-ehci"; + reg = <0x0 0xfd800000 0x0 0x40000>; + interrupts = ; + clocks = <&cru HCLK_USB2HOST0>, <&cru HCLK_USB2HOST0_ARB>, + <&cru PCLK_USB>; + phys = <&usb2phy1_otg>; + phy-names = "usb"; + status = "disabled"; + }; + + usb_host0_ohci: usb@fd840000 { + compatible = "generic-ohci"; + reg = <0x0 0xfd840000 0x0 0x40000>; + interrupts = ; + clocks = <&cru HCLK_USB2HOST0>, <&cru HCLK_USB2HOST0_ARB>, + <&cru PCLK_USB>; + phys = <&usb2phy1_otg>; + phy-names = "usb"; + status = "disabled"; + }; + + usb_host1_ehci: usb@fd880000 { + compatible = "generic-ehci"; + reg = <0x0 0xfd880000 0x0 0x40000>; + interrupts = ; + clocks = <&cru HCLK_USB2HOST1>, <&cru HCLK_USB2HOST1_ARB>, + <&cru PCLK_USB>; + phys = <&usb2phy1_host>; + phy-names = "usb"; + status = "disabled"; + }; + + usb_host1_ohci: usb@fd8c0000 { + compatible = "generic-ohci"; + reg = <0x0 0xfd8c0000 0x0 0x40000>; + interrupts = ; + clocks = <&cru HCLK_USB2HOST1>, <&cru HCLK_USB2HOST1_ARB>, + <&cru PCLK_USB>; + phys = <&usb2phy1_host>; + phy-names = "usb"; + status = "disabled"; + }; + + pmugrf: syscon@fdc20000 { + compatible = "rockchip,rk3568-pmugrf", "syscon", "simple-mfd"; + reg = <0x0 0xfdc20000 0x0 0x10000>; + + pmu_io_domains: io-domains { + compatible = "rockchip,rk3568-pmu-io-voltage-domain"; + status = "disabled"; + }; + }; + + pipegrf: syscon@fdc50000 { + reg = <0x0 0xfdc50000 0x0 0x1000>; + }; + + grf: syscon@fdc60000 { + compatible = "rockchip,rk3568-grf", "syscon", "simple-mfd"; + reg = <0x0 0xfdc60000 0x0 0x10000>; + }; + + pipe_phy_grf1: syscon@fdc80000 { + compatible = "rockchip,rk3568-pipe-phy-grf", "syscon"; + reg = <0x0 0xfdc80000 0x0 0x1000>; + }; + + pipe_phy_grf2: syscon@fdc90000 { + compatible = "rockchip,rk3568-pipe-phy-grf", "syscon"; + reg = <0x0 0xfdc90000 0x0 0x1000>; + }; + + usb2phy0_grf: syscon@fdca0000 { + compatible = "rockchip,rk3568-usb2phy-grf", "syscon"; + reg = <0x0 0xfdca0000 0x0 0x8000>; + }; + + usb2phy1_grf: syscon@fdca8000 { + compatible = "rockchip,rk3568-usb2phy-grf", "syscon"; + reg = <0x0 0xfdca8000 0x0 0x8000>; + }; + + pmucru: clock-controller@fdd00000 { + compatible = "rockchip,rk3568-pmucru"; + reg = <0x0 0xfdd00000 0x0 0x1000>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + cru: clock-controller@fdd20000 { + compatible = "rockchip,rk3568-cru"; + reg = <0x0 0xfdd20000 0x0 0x1000>; + clocks = <&xin24m>; + clock-names = "xin24m"; + #clock-cells = <1>; + #reset-cells = <1>; + assigned-clocks = <&cru PLL_GPLL>, <&pmucru PLL_PPLL>; + assigned-clock-rates = <1200000000>, <200000000>; + rockchip,grf = <&grf>; + }; + + i2c0: i2c@fdd40000 { + compatible = "rockchip,rk3568-i2c", "rockchip,rk3399-i2c"; + reg = <0x0 0xfdd40000 0x0 0x1000>; + interrupts = ; + clocks = <&pmucru CLK_I2C0>, <&pmucru PCLK_I2C0>; + clock-names = "i2c", "pclk"; + pinctrl-0 = <&i2c0_xfer>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + uart0: serial@fdd50000 { + compatible = "rockchip,rk3568-uart", "snps,dw-apb-uart"; + reg = <0x0 0xfdd50000 0x0 0x100>; + interrupts = ; + clocks = <&pmucru SCLK_UART0>, <&pmucru PCLK_UART0>; + clock-names = "baudclk", "apb_pclk"; + dmas = <&dmac0 0>, <&dmac0 1>; + pinctrl-0 = <&uart0_xfer>; + pinctrl-names = "default"; + reg-io-width = <4>; + reg-shift = <2>; + status = "disabled"; + }; + + pwm0: pwm@fdd70000 { + compatible = "rockchip,rk3568-pwm", "rockchip,rk3328-pwm"; + reg = <0x0 0xfdd70000 0x0 0x10>; + clocks = <&pmucru CLK_PWM0>, <&pmucru PCLK_PWM0>; + clock-names = "pwm", "pclk"; + pinctrl-0 = <&pwm0m0_pins>; + pinctrl-names = "default"; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm1: pwm@fdd70010 { + compatible = "rockchip,rk3568-pwm", "rockchip,rk3328-pwm"; + reg = <0x0 0xfdd70010 0x0 0x10>; + clocks = <&pmucru CLK_PWM0>, <&pmucru PCLK_PWM0>; + clock-names = "pwm", "pclk"; + pinctrl-0 = <&pwm1m0_pins>; + pinctrl-names = "default"; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm2: pwm@fdd70020 { + compatible = "rockchip,rk3568-pwm", "rockchip,rk3328-pwm"; + reg = <0x0 0xfdd70020 0x0 0x10>; + clocks = <&pmucru CLK_PWM0>, <&pmucru PCLK_PWM0>; + clock-names = "pwm", "pclk"; + pinctrl-0 = <&pwm2m0_pins>; + pinctrl-names = "default"; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm3: pwm@fdd70030 { + compatible = "rockchip,rk3568-pwm", "rockchip,rk3328-pwm"; + reg = <0x0 0xfdd70030 0x0 0x10>; + clocks = <&pmucru CLK_PWM0>, <&pmucru PCLK_PWM0>; + clock-names = "pwm", "pclk"; + pinctrl-0 = <&pwm3_pins>; + pinctrl-names = "default"; + #pwm-cells = <3>; + status = "disabled"; + }; + + pmu: power-management@fdd90000 { + compatible = "rockchip,rk3568-pmu", "syscon", "simple-mfd"; + reg = <0x0 0xfdd90000 0x0 0x1000>; + + power: power-controller { + compatible = "rockchip,rk3568-power-controller"; + #power-domain-cells = <1>; + #address-cells = <1>; + #size-cells = <0>; + + /* These power domains are grouped by VD_GPU */ + power-domain@RK3568_PD_GPU { + reg = ; + clocks = <&cru ACLK_GPU_PRE>, + <&cru PCLK_GPU_PRE>; + pm_qos = <&qos_gpu>; + #power-domain-cells = <0>; + }; + + /* These power domains are grouped by VD_LOGIC */ + power-domain@RK3568_PD_VI { + reg = ; + clocks = <&cru HCLK_VI>, + <&cru PCLK_VI>; + pm_qos = <&qos_isp>, + <&qos_vicap0>, + <&qos_vicap1>; + #power-domain-cells = <0>; + }; + + power-domain@RK3568_PD_VO { + reg = ; + clocks = <&cru HCLK_VO>, + <&cru PCLK_VO>, + <&cru ACLK_VOP_PRE>; + pm_qos = <&qos_hdcp>, + <&qos_vop_m0>, + <&qos_vop_m1>; + #power-domain-cells = <0>; + }; + + power-domain@RK3568_PD_RGA { + reg = ; + clocks = <&cru HCLK_RGA_PRE>, + <&cru PCLK_RGA_PRE>; + pm_qos = <&qos_ebc>, + <&qos_iep>, + <&qos_jpeg_dec>, + <&qos_jpeg_enc>, + <&qos_rga_rd>, + <&qos_rga_wr>; + #power-domain-cells = <0>; + }; + + power-domain@RK3568_PD_VPU { + reg = ; + clocks = <&cru HCLK_VPU_PRE>; + pm_qos = <&qos_vpu>; + #power-domain-cells = <0>; + }; + + power-domain@RK3568_PD_RKVDEC { + clocks = <&cru HCLK_RKVDEC_PRE>; + reg = ; + pm_qos = <&qos_rkvdec>; + #power-domain-cells = <0>; + }; + + power-domain@RK3568_PD_RKVENC { + reg = ; + clocks = <&cru HCLK_RKVENC_PRE>; + pm_qos = <&qos_rkvenc_rd_m0>, + <&qos_rkvenc_rd_m1>, + <&qos_rkvenc_wr_m0>; + #power-domain-cells = <0>; + }; + }; + }; + + gpu: gpu@fde60000 { + compatible = "rockchip,rk3568-mali", "arm,mali-bifrost"; + reg = <0x0 0xfde60000 0x0 0x4000>; + interrupts = , + , + ; + interrupt-names = "job", "mmu", "gpu"; + clocks = <&scmi_clk 1>, <&cru CLK_GPU>; + clock-names = "gpu", "bus"; + #cooling-cells = <2>; + operating-points-v2 = <&gpu_opp_table>; + power-domains = <&power RK3568_PD_GPU>; + status = "disabled"; + }; + + sdmmc2: mmc@fe000000 { + compatible = "rockchip,rk3568-dw-mshc", "rockchip,rk3288-dw-mshc"; + reg = <0x0 0xfe000000 0x0 0x4000>; + interrupts = ; + clocks = <&cru HCLK_SDMMC2>, <&cru CLK_SDMMC2>, + <&cru SCLK_SDMMC2_DRV>, <&cru SCLK_SDMMC2_SAMPLE>; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; + fifo-depth = <0x100>; + max-frequency = <150000000>; + resets = <&cru SRST_SDMMC2>; + reset-names = "reset"; + status = "disabled"; + }; + + gmac1: ethernet@fe010000 { + compatible = "rockchip,rk3568-gmac", "snps,dwmac-4.20a"; + reg = <0x0 0xfe010000 0x0 0x10000>; + interrupts = , + ; + interrupt-names = "macirq", "eth_wake_irq"; + clocks = <&cru SCLK_GMAC1>, <&cru SCLK_GMAC1_RX_TX>, + <&cru SCLK_GMAC1_RX_TX>, <&cru CLK_MAC1_REFOUT>, + <&cru ACLK_GMAC1>, <&cru PCLK_GMAC1>, + <&cru SCLK_GMAC1_RX_TX>, <&cru CLK_GMAC1_PTP_REF>; + clock-names = "stmmaceth", "mac_clk_rx", + "mac_clk_tx", "clk_mac_refout", + "aclk_mac", "pclk_mac", + "clk_mac_speed", "ptp_ref"; + resets = <&cru SRST_A_GMAC1>; + reset-names = "stmmaceth"; + rockchip,grf = <&grf>; + snps,axi-config = <&gmac1_stmmac_axi_setup>; + snps,mixed-burst; + snps,mtl-rx-config = <&gmac1_mtl_rx_setup>; + snps,mtl-tx-config = <&gmac1_mtl_tx_setup>; + snps,tso; + status = "disabled"; + + mdio1: mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <0x1>; + #size-cells = <0x0>; + }; + + gmac1_stmmac_axi_setup: stmmac-axi-config { + snps,blen = <0 0 0 0 16 8 4>; + snps,rd_osr_lmt = <8>; + snps,wr_osr_lmt = <4>; + }; + + gmac1_mtl_rx_setup: rx-queues-config { + snps,rx-queues-to-use = <1>; + queue0 {}; + }; + + gmac1_mtl_tx_setup: tx-queues-config { + snps,tx-queues-to-use = <1>; + queue0 {}; + }; + }; + + vop: vop@fe040000 { + reg = <0x0 0xfe040000 0x0 0x3000>, <0x0 0xfe044000 0x0 0x1000>; + reg-names = "vop", "gamma-lut"; + interrupts = ; + clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>, <&cru DCLK_VOP0>, + <&cru DCLK_VOP1>, <&cru DCLK_VOP2>; + clock-names = "aclk", "hclk", "dclk_vp0", "dclk_vp1", "dclk_vp2"; + iommus = <&vop_mmu>; + power-domains = <&power RK3568_PD_VO>; + rockchip,grf = <&grf>; + status = "disabled"; + + vop_out: ports { + #address-cells = <1>; + #size-cells = <0>; + + vp0: port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + }; + + vp1: port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + }; + + vp2: port@2 { + reg = <2>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; + }; + + vop_mmu: iommu@fe043e00 { + compatible = "rockchip,rk3568-iommu"; + reg = <0x0 0xfe043e00 0x0 0x100>, <0x0 0xfe043f00 0x0 0x100>; + interrupts = ; + clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>; + clock-names = "aclk", "iface"; + #iommu-cells = <0>; + status = "disabled"; + }; + + hdmi: hdmi@fe0a0000 { + compatible = "rockchip,rk3568-dw-hdmi"; + reg = <0x0 0xfe0a0000 0x0 0x20000>; + interrupts = ; + clocks = <&cru PCLK_HDMI_HOST>, + <&cru CLK_HDMI_SFR>, + <&cru CLK_HDMI_CEC>, + <&pmucru CLK_HDMI_REF>, + <&cru HCLK_VO>; + clock-names = "iahb", "isfr", "cec", "ref"; + pinctrl-names = "default"; + pinctrl-0 = <&hdmitx_scl &hdmitx_sda &hdmitxm0_cec>; + power-domains = <&power RK3568_PD_VO>; + reg-io-width = <4>; + rockchip,grf = <&grf>; + #sound-dai-cells = <0>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + hdmi_in: port@0 { + reg = <0>; + }; + + hdmi_out: port@1 { + reg = <1>; + }; + }; + }; + + qos_gpu: qos@fe128000 { + compatible = "rockchip,rk3568-qos", "syscon"; + reg = <0x0 0xfe128000 0x0 0x20>; + }; + + qos_rkvenc_rd_m0: qos@fe138080 { + compatible = "rockchip,rk3568-qos", "syscon"; + reg = <0x0 0xfe138080 0x0 0x20>; + }; + + qos_rkvenc_rd_m1: qos@fe138100 { + compatible = "rockchip,rk3568-qos", "syscon"; + reg = <0x0 0xfe138100 0x0 0x20>; + }; + + qos_rkvenc_wr_m0: qos@fe138180 { + compatible = "rockchip,rk3568-qos", "syscon"; + reg = <0x0 0xfe138180 0x0 0x20>; + }; + + qos_isp: qos@fe148000 { + compatible = "rockchip,rk3568-qos", "syscon"; + reg = <0x0 0xfe148000 0x0 0x20>; + }; + + qos_vicap0: qos@fe148080 { + compatible = "rockchip,rk3568-qos", "syscon"; + reg = <0x0 0xfe148080 0x0 0x20>; + }; + + qos_vicap1: qos@fe148100 { + compatible = "rockchip,rk3568-qos", "syscon"; + reg = <0x0 0xfe148100 0x0 0x20>; + }; + + qos_vpu: qos@fe150000 { + compatible = "rockchip,rk3568-qos", "syscon"; + reg = <0x0 0xfe150000 0x0 0x20>; + }; + + qos_ebc: qos@fe158000 { + compatible = "rockchip,rk3568-qos", "syscon"; + reg = <0x0 0xfe158000 0x0 0x20>; + }; + + qos_iep: qos@fe158100 { + compatible = "rockchip,rk3568-qos", "syscon"; + reg = <0x0 0xfe158100 0x0 0x20>; + }; + + qos_jpeg_dec: qos@fe158180 { + compatible = "rockchip,rk3568-qos", "syscon"; + reg = <0x0 0xfe158180 0x0 0x20>; + }; + + qos_jpeg_enc: qos@fe158200 { + compatible = "rockchip,rk3568-qos", "syscon"; + reg = <0x0 0xfe158200 0x0 0x20>; + }; + + qos_rga_rd: qos@fe158280 { + compatible = "rockchip,rk3568-qos", "syscon"; + reg = <0x0 0xfe158280 0x0 0x20>; + }; + + qos_rga_wr: qos@fe158300 { + compatible = "rockchip,rk3568-qos", "syscon"; + reg = <0x0 0xfe158300 0x0 0x20>; + }; + + qos_npu: qos@fe180000 { + compatible = "rockchip,rk3568-qos", "syscon"; + reg = <0x0 0xfe180000 0x0 0x20>; + }; + + qos_pcie2x1: qos@fe190000 { + compatible = "rockchip,rk3568-qos", "syscon"; + reg = <0x0 0xfe190000 0x0 0x20>; + }; + + qos_sata1: qos@fe190280 { + compatible = "rockchip,rk3568-qos", "syscon"; + reg = <0x0 0xfe190280 0x0 0x20>; + }; + + qos_sata2: qos@fe190300 { + compatible = "rockchip,rk3568-qos", "syscon"; + reg = <0x0 0xfe190300 0x0 0x20>; + }; + + qos_usb3_0: qos@fe190380 { + compatible = "rockchip,rk3568-qos", "syscon"; + reg = <0x0 0xfe190380 0x0 0x20>; + }; + + qos_usb3_1: qos@fe190400 { + compatible = "rockchip,rk3568-qos", "syscon"; + reg = <0x0 0xfe190400 0x0 0x20>; + }; + + qos_rkvdec: qos@fe198000 { + compatible = "rockchip,rk3568-qos", "syscon"; + reg = <0x0 0xfe198000 0x0 0x20>; + }; + + qos_hdcp: qos@fe1a8000 { + compatible = "rockchip,rk3568-qos", "syscon"; + reg = <0x0 0xfe1a8000 0x0 0x20>; + }; + + qos_vop_m0: qos@fe1a8080 { + compatible = "rockchip,rk3568-qos", "syscon"; + reg = <0x0 0xfe1a8080 0x0 0x20>; + }; + + qos_vop_m1: qos@fe1a8100 { + compatible = "rockchip,rk3568-qos", "syscon"; + reg = <0x0 0xfe1a8100 0x0 0x20>; + }; + + pcie2x1: pcie@fe260000 { + compatible = "rockchip,rk3568-pcie"; + reg = <0x3 0xc0000000 0x0 0x00400000>, + <0x0 0xfe260000 0x0 0x00010000>, + <0x3 0x3f000000 0x0 0x01000000>; + reg-names = "dbi", "apb", "config"; + interrupts = , + , + , + , + ; + interrupt-names = "sys", "pmc", "msi", "legacy", "err"; + bus-range = <0x0 0xf>; + clocks = <&cru ACLK_PCIE20_MST>, <&cru ACLK_PCIE20_SLV>, + <&cru ACLK_PCIE20_DBI>, <&cru PCLK_PCIE20>, + <&cru CLK_PCIE20_AUX_NDFT>; + clock-names = "aclk_mst", "aclk_slv", + "aclk_dbi", "pclk", "aux"; + device_type = "pci"; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &pcie_intc 0>, + <0 0 0 2 &pcie_intc 1>, + <0 0 0 3 &pcie_intc 2>, + <0 0 0 4 &pcie_intc 3>; + linux,pci-domain = <0>; + num-ib-windows = <6>; + num-ob-windows = <2>; + max-link-speed = <2>; + msi-map = <0x0 &gic 0x0 0x1000>; + num-lanes = <1>; + phys = <&combphy2 PHY_TYPE_PCIE>; + phy-names = "pcie-phy"; + power-domains = <&power RK3568_PD_PIPE>; + ranges = <0x01000000 0x0 0x3ef00000 0x3 0x3ef00000 0x0 0x00100000 + 0x02000000 0x0 0x00000000 0x3 0x00000000 0x0 0x3ef00000>; + resets = <&cru SRST_PCIE20_POWERUP>; + reset-names = "pipe"; + #address-cells = <3>; + #size-cells = <2>; + status = "disabled"; + + pcie_intc: legacy-interrupt-controller { + #address-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; + interrupt-parent = <&gic>; + interrupts = ; + }; + }; + + sdmmc0: mmc@fe2b0000 { + compatible = "rockchip,rk3568-dw-mshc", "rockchip,rk3288-dw-mshc"; + reg = <0x0 0xfe2b0000 0x0 0x4000>; + interrupts = ; + clocks = <&cru HCLK_SDMMC0>, <&cru CLK_SDMMC0>, + <&cru SCLK_SDMMC0_DRV>, <&cru SCLK_SDMMC0_SAMPLE>; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; + fifo-depth = <0x100>; + max-frequency = <150000000>; + resets = <&cru SRST_SDMMC0>; + reset-names = "reset"; + status = "disabled"; + }; + + sdmmc1: mmc@fe2c0000 { + compatible = "rockchip,rk3568-dw-mshc", "rockchip,rk3288-dw-mshc"; + reg = <0x0 0xfe2c0000 0x0 0x4000>; + interrupts = ; + clocks = <&cru HCLK_SDMMC1>, <&cru CLK_SDMMC1>, + <&cru SCLK_SDMMC1_DRV>, <&cru SCLK_SDMMC1_SAMPLE>; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; + fifo-depth = <0x100>; + max-frequency = <150000000>; + resets = <&cru SRST_SDMMC1>; + reset-names = "reset"; + status = "disabled"; + }; + + sfc: spi@fe300000 { + compatible = "rockchip,sfc"; + reg = <0x0 0xfe300000 0x0 0x4000>; + interrupts = ; + clocks = <&cru SCLK_SFC>, <&cru HCLK_SFC>; + clock-names = "clk_sfc", "hclk_sfc"; + pinctrl-0 = <&fspi_pins>; + pinctrl-names = "default"; + status = "disabled"; + }; + + sdhci: mmc@fe310000 { + compatible = "rockchip,rk3568-dwcmshc"; + reg = <0x0 0xfe310000 0x0 0x10000>; + interrupts = ; + assigned-clocks = <&cru BCLK_EMMC>, <&cru TCLK_EMMC>; + assigned-clock-rates = <200000000>, <24000000>; + clocks = <&cru CCLK_EMMC>, <&cru HCLK_EMMC>, + <&cru ACLK_EMMC>, <&cru BCLK_EMMC>, + <&cru TCLK_EMMC>; + clock-names = "core", "bus", "axi", "block", "timer"; + status = "disabled"; + }; + + spdif: spdif@fe460000 { + compatible = "rockchip,rk3568-spdif"; + reg = <0x0 0xfe460000 0x0 0x1000>; + interrupts = ; + clock-names = "mclk", "hclk"; + clocks = <&cru MCLK_SPDIF_8CH>, <&cru HCLK_SPDIF_8CH>; + dmas = <&dmac1 1>; + dma-names = "tx"; + pinctrl-names = "default"; + pinctrl-0 = <&spdifm0_tx>; + #sound-dai-cells = <0>; + status = "disabled"; + }; + + i2s0_8ch: i2s@fe400000 { + compatible = "rockchip,rk3568-i2s-tdm"; + reg = <0x0 0xfe400000 0x0 0x1000>; + interrupts = ; + assigned-clocks = <&cru CLK_I2S0_8CH_TX_SRC>, <&cru CLK_I2S0_8CH_RX_SRC>; + assigned-clock-rates = <1188000000>, <1188000000>; + clocks = <&cru MCLK_I2S0_8CH_TX>, <&cru MCLK_I2S0_8CH_RX>, <&cru HCLK_I2S0_8CH>; + clock-names = "mclk_tx", "mclk_rx", "hclk"; + dmas = <&dmac1 0>; + dma-names = "tx"; + resets = <&cru SRST_M_I2S0_8CH_TX>, <&cru SRST_M_I2S0_8CH_RX>; + reset-names = "tx-m", "rx-m"; + rockchip,grf = <&grf>; + #sound-dai-cells = <0>; + status = "disabled"; + }; + + i2s1_8ch: i2s@fe410000 { + compatible = "rockchip,rk3568-i2s-tdm"; + reg = <0x0 0xfe410000 0x0 0x1000>; + interrupts = ; + assigned-clocks = <&cru CLK_I2S1_8CH_TX_SRC>, <&cru CLK_I2S1_8CH_RX_SRC>; + assigned-clock-rates = <1188000000>, <1188000000>; + clocks = <&cru MCLK_I2S1_8CH_TX>, <&cru MCLK_I2S1_8CH_RX>, + <&cru HCLK_I2S1_8CH>; + clock-names = "mclk_tx", "mclk_rx", "hclk"; + dmas = <&dmac1 3>, <&dmac1 2>; + dma-names = "rx", "tx"; + resets = <&cru SRST_M_I2S1_8CH_TX>, <&cru SRST_M_I2S1_8CH_RX>; + reset-names = "tx-m", "rx-m"; + rockchip,grf = <&grf>; + pinctrl-names = "default"; + pinctrl-0 = <&i2s1m0_sclktx &i2s1m0_sclkrx + &i2s1m0_lrcktx &i2s1m0_lrckrx + &i2s1m0_sdi0 &i2s1m0_sdi1 + &i2s1m0_sdi2 &i2s1m0_sdi3 + &i2s1m0_sdo0 &i2s1m0_sdo1 + &i2s1m0_sdo2 &i2s1m0_sdo3>; + #sound-dai-cells = <0>; + status = "disabled"; + }; + + i2s3_2ch: i2s@fe430000 { + compatible = "rockchip,rk3568-i2s-tdm"; + reg = <0x0 0xfe430000 0x0 0x1000>; + interrupts = ; + clocks = <&cru MCLK_I2S3_2CH_TX>, <&cru MCLK_I2S3_2CH_RX>, + <&cru HCLK_I2S3_2CH>; + clock-names = "mclk_tx", "mclk_rx", "hclk"; + dmas = <&dmac1 6>, <&dmac1 7>; + dma-names = "tx", "rx"; + resets = <&cru SRST_M_I2S3_2CH_TX>, <&cru SRST_M_I2S3_2CH_RX>; + reset-names = "tx-m", "rx-m"; + rockchip,grf = <&grf>; + #sound-dai-cells = <0>; + status = "disabled"; + }; + + pdm: pdm@fe440000 { + compatible = "rockchip,rk3568-pdm"; + reg = <0x0 0xfe440000 0x0 0x1000>; + interrupts = ; + clocks = <&cru MCLK_PDM>, <&cru HCLK_PDM>; + clock-names = "pdm_clk", "pdm_hclk"; + dmas = <&dmac1 9>; + dma-names = "rx"; + pinctrl-0 = <&pdmm0_clk + &pdmm0_clk1 + &pdmm0_sdi0 + &pdmm0_sdi1 + &pdmm0_sdi2 + &pdmm0_sdi3>; + pinctrl-names = "default"; + resets = <&cru SRST_M_PDM>; + reset-names = "pdm-m"; + #sound-dai-cells = <0>; + status = "disabled"; + }; + + dmac0: dma-controller@fe530000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0x0 0xfe530000 0x0 0x4000>; + interrupts = , + ; + arm,pl330-periph-burst; + clocks = <&cru ACLK_BUS>; + clock-names = "apb_pclk"; + #dma-cells = <1>; + }; + + dmac1: dma-controller@fe550000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0x0 0xfe550000 0x0 0x4000>; + interrupts = , + ; + arm,pl330-periph-burst; + clocks = <&cru ACLK_BUS>; + clock-names = "apb_pclk"; + #dma-cells = <1>; + }; + + i2c1: i2c@fe5a0000 { + compatible = "rockchip,rk3568-i2c", "rockchip,rk3399-i2c"; + reg = <0x0 0xfe5a0000 0x0 0x1000>; + interrupts = ; + clocks = <&cru CLK_I2C1>, <&cru PCLK_I2C1>; + clock-names = "i2c", "pclk"; + pinctrl-0 = <&i2c1_xfer>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c2: i2c@fe5b0000 { + compatible = "rockchip,rk3568-i2c", "rockchip,rk3399-i2c"; + reg = <0x0 0xfe5b0000 0x0 0x1000>; + interrupts = ; + clocks = <&cru CLK_I2C2>, <&cru PCLK_I2C2>; + clock-names = "i2c", "pclk"; + pinctrl-0 = <&i2c2m0_xfer>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c3: i2c@fe5c0000 { + compatible = "rockchip,rk3568-i2c", "rockchip,rk3399-i2c"; + reg = <0x0 0xfe5c0000 0x0 0x1000>; + interrupts = ; + clocks = <&cru CLK_I2C3>, <&cru PCLK_I2C3>; + clock-names = "i2c", "pclk"; + pinctrl-0 = <&i2c3m0_xfer>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c4: i2c@fe5d0000 { + compatible = "rockchip,rk3568-i2c", "rockchip,rk3399-i2c"; + reg = <0x0 0xfe5d0000 0x0 0x1000>; + interrupts = ; + clocks = <&cru CLK_I2C4>, <&cru PCLK_I2C4>; + clock-names = "i2c", "pclk"; + pinctrl-0 = <&i2c4m0_xfer>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c5: i2c@fe5e0000 { + compatible = "rockchip,rk3568-i2c", "rockchip,rk3399-i2c"; + reg = <0x0 0xfe5e0000 0x0 0x1000>; + interrupts = ; + clocks = <&cru CLK_I2C5>, <&cru PCLK_I2C5>; + clock-names = "i2c", "pclk"; + pinctrl-0 = <&i2c5m0_xfer>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + wdt: watchdog@fe600000 { + compatible = "rockchip,rk3568-wdt", "snps,dw-wdt"; + reg = <0x0 0xfe600000 0x0 0x100>; + interrupts = ; + clocks = <&cru TCLK_WDT_NS>, <&cru PCLK_WDT_NS>; + clock-names = "tclk", "pclk"; + }; + + spi0: spi@fe610000 { + compatible = "rockchip,rk3568-spi", "rockchip,rk3066-spi"; + reg = <0x0 0xfe610000 0x0 0x1000>; + interrupts = ; + clocks = <&cru CLK_SPI0>, <&cru PCLK_SPI0>; + clock-names = "spiclk", "apb_pclk"; + dmas = <&dmac0 20>, <&dmac0 21>; + dma-names = "tx", "rx"; + pinctrl-names = "default"; + pinctrl-0 = <&spi0m0_cs0 &spi0m0_cs1 &spi0m0_pins>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi1: spi@fe620000 { + compatible = "rockchip,rk3568-spi", "rockchip,rk3066-spi"; + reg = <0x0 0xfe620000 0x0 0x1000>; + interrupts = ; + clocks = <&cru CLK_SPI1>, <&cru PCLK_SPI1>; + clock-names = "spiclk", "apb_pclk"; + dmas = <&dmac0 22>, <&dmac0 23>; + dma-names = "tx", "rx"; + pinctrl-names = "default"; + pinctrl-0 = <&spi1m0_cs0 &spi1m0_cs1 &spi1m0_pins>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi2: spi@fe630000 { + compatible = "rockchip,rk3568-spi", "rockchip,rk3066-spi"; + reg = <0x0 0xfe630000 0x0 0x1000>; + interrupts = ; + clocks = <&cru CLK_SPI2>, <&cru PCLK_SPI2>; + clock-names = "spiclk", "apb_pclk"; + dmas = <&dmac0 24>, <&dmac0 25>; + dma-names = "tx", "rx"; + pinctrl-names = "default"; + pinctrl-0 = <&spi2m0_cs0 &spi2m0_cs1 &spi2m0_pins>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi3: spi@fe640000 { + compatible = "rockchip,rk3568-spi", "rockchip,rk3066-spi"; + reg = <0x0 0xfe640000 0x0 0x1000>; + interrupts = ; + clocks = <&cru CLK_SPI3>, <&cru PCLK_SPI3>; + clock-names = "spiclk", "apb_pclk"; + dmas = <&dmac0 26>, <&dmac0 27>; + dma-names = "tx", "rx"; + pinctrl-names = "default"; + pinctrl-0 = <&spi3m0_cs0 &spi3m0_cs1 &spi3m0_pins>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + uart1: serial@fe650000 { + compatible = "rockchip,rk3568-uart", "snps,dw-apb-uart"; + reg = <0x0 0xfe650000 0x0 0x100>; + interrupts = ; + clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>; + clock-names = "baudclk", "apb_pclk"; + dmas = <&dmac0 2>, <&dmac0 3>; + pinctrl-0 = <&uart1m0_xfer>; + pinctrl-names = "default"; + reg-io-width = <4>; + reg-shift = <2>; + status = "disabled"; + }; + + uart2: serial@fe660000 { + compatible = "rockchip,rk3568-uart", "snps,dw-apb-uart"; + reg = <0x0 0xfe660000 0x0 0x100>; + interrupts = ; + clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>; + clock-names = "baudclk", "apb_pclk"; + dmas = <&dmac0 4>, <&dmac0 5>; + pinctrl-0 = <&uart2m0_xfer>; + pinctrl-names = "default"; + reg-io-width = <4>; + reg-shift = <2>; + status = "disabled"; + }; + + uart3: serial@fe670000 { + compatible = "rockchip,rk3568-uart", "snps,dw-apb-uart"; + reg = <0x0 0xfe670000 0x0 0x100>; + interrupts = ; + clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>; + clock-names = "baudclk", "apb_pclk"; + dmas = <&dmac0 6>, <&dmac0 7>; + pinctrl-0 = <&uart3m0_xfer>; + pinctrl-names = "default"; + reg-io-width = <4>; + reg-shift = <2>; + status = "disabled"; + }; + + uart4: serial@fe680000 { + compatible = "rockchip,rk3568-uart", "snps,dw-apb-uart"; + reg = <0x0 0xfe680000 0x0 0x100>; + interrupts = ; + clocks = <&cru SCLK_UART4>, <&cru PCLK_UART4>; + clock-names = "baudclk", "apb_pclk"; + dmas = <&dmac0 8>, <&dmac0 9>; + pinctrl-0 = <&uart4m0_xfer>; + pinctrl-names = "default"; + reg-io-width = <4>; + reg-shift = <2>; + status = "disabled"; + }; + + uart5: serial@fe690000 { + compatible = "rockchip,rk3568-uart", "snps,dw-apb-uart"; + reg = <0x0 0xfe690000 0x0 0x100>; + interrupts = ; + clocks = <&cru SCLK_UART5>, <&cru PCLK_UART5>; + clock-names = "baudclk", "apb_pclk"; + dmas = <&dmac0 10>, <&dmac0 11>; + pinctrl-0 = <&uart5m0_xfer>; + pinctrl-names = "default"; + reg-io-width = <4>; + reg-shift = <2>; + status = "disabled"; + }; + + uart6: serial@fe6a0000 { + compatible = "rockchip,rk3568-uart", "snps,dw-apb-uart"; + reg = <0x0 0xfe6a0000 0x0 0x100>; + interrupts = ; + clocks = <&cru SCLK_UART6>, <&cru PCLK_UART6>; + clock-names = "baudclk", "apb_pclk"; + dmas = <&dmac0 12>, <&dmac0 13>; + pinctrl-0 = <&uart6m0_xfer>; + pinctrl-names = "default"; + reg-io-width = <4>; + reg-shift = <2>; + status = "disabled"; + }; + + uart7: serial@fe6b0000 { + compatible = "rockchip,rk3568-uart", "snps,dw-apb-uart"; + reg = <0x0 0xfe6b0000 0x0 0x100>; + interrupts = ; + clocks = <&cru SCLK_UART7>, <&cru PCLK_UART7>; + clock-names = "baudclk", "apb_pclk"; + dmas = <&dmac0 14>, <&dmac0 15>; + pinctrl-0 = <&uart7m0_xfer>; + pinctrl-names = "default"; + reg-io-width = <4>; + reg-shift = <2>; + status = "disabled"; + }; + + uart8: serial@fe6c0000 { + compatible = "rockchip,rk3568-uart", "snps,dw-apb-uart"; + reg = <0x0 0xfe6c0000 0x0 0x100>; + interrupts = ; + clocks = <&cru SCLK_UART8>, <&cru PCLK_UART8>; + clock-names = "baudclk", "apb_pclk"; + dmas = <&dmac0 16>, <&dmac0 17>; + pinctrl-0 = <&uart8m0_xfer>; + pinctrl-names = "default"; + reg-io-width = <4>; + reg-shift = <2>; + status = "disabled"; + }; + + uart9: serial@fe6d0000 { + compatible = "rockchip,rk3568-uart", "snps,dw-apb-uart"; + reg = <0x0 0xfe6d0000 0x0 0x100>; + interrupts = ; + clocks = <&cru SCLK_UART9>, <&cru PCLK_UART9>; + clock-names = "baudclk", "apb_pclk"; + dmas = <&dmac0 18>, <&dmac0 19>; + pinctrl-0 = <&uart9m0_xfer>; + pinctrl-names = "default"; + reg-io-width = <4>; + reg-shift = <2>; + status = "disabled"; + }; + + thermal_zones: thermal-zones { + cpu_thermal: cpu-thermal { + polling-delay-passive = <100>; + polling-delay = <1000>; + + thermal-sensors = <&tsadc 0>; + + trips { + cpu_alert0: cpu_alert0 { + temperature = <70000>; + hysteresis = <2000>; + type = "passive"; + }; + cpu_alert1: cpu_alert1 { + temperature = <75000>; + hysteresis = <2000>; + type = "passive"; + }; + cpu_crit: cpu_crit { + temperature = <95000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu_alert0>; + cooling-device = + <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + gpu_thermal: gpu-thermal { + polling-delay-passive = <20>; /* milliseconds */ + polling-delay = <1000>; /* milliseconds */ + + thermal-sensors = <&tsadc 1>; + + trips { + gpu_threshold: gpu-threshold { + temperature = <70000>; + hysteresis = <2000>; + type = "passive"; + }; + gpu_target: gpu-target { + temperature = <75000>; + hysteresis = <2000>; + type = "passive"; + }; + gpu_crit: gpu-crit { + temperature = <95000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&gpu_target>; + cooling-device = + <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + }; + + tsadc: tsadc@fe710000 { + compatible = "rockchip,rk3568-tsadc"; + reg = <0x0 0xfe710000 0x0 0x100>; + interrupts = ; + assigned-clocks = <&cru CLK_TSADC_TSEN>, <&cru CLK_TSADC>; + assigned-clock-rates = <17000000>, <700000>; + clocks = <&cru CLK_TSADC>, <&cru PCLK_TSADC>; + clock-names = "tsadc", "apb_pclk"; + resets = <&cru SRST_P_TSADC>, <&cru SRST_TSADC>, + <&cru SRST_TSADCPHY>; + rockchip,grf = <&grf>; + rockchip,hw-tshut-temp = <95000>; + pinctrl-names = "init", "default", "sleep"; + pinctrl-0 = <&tsadc_pin>; + pinctrl-1 = <&tsadc_shutorg>; + pinctrl-2 = <&tsadc_pin>; + #thermal-sensor-cells = <1>; + status = "disabled"; + }; + + saradc: saradc@fe720000 { + compatible = "rockchip,rk3568-saradc", "rockchip,rk3399-saradc"; + reg = <0x0 0xfe720000 0x0 0x100>; + interrupts = ; + clocks = <&cru CLK_SARADC>, <&cru PCLK_SARADC>; + clock-names = "saradc", "apb_pclk"; + resets = <&cru SRST_P_SARADC>; + reset-names = "saradc-apb"; + #io-channel-cells = <1>; + status = "disabled"; + }; + + pwm4: pwm@fe6e0000 { + compatible = "rockchip,rk3568-pwm", "rockchip,rk3328-pwm"; + reg = <0x0 0xfe6e0000 0x0 0x10>; + clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>; + clock-names = "pwm", "pclk"; + pinctrl-0 = <&pwm4_pins>; + pinctrl-names = "default"; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm5: pwm@fe6e0010 { + compatible = "rockchip,rk3568-pwm", "rockchip,rk3328-pwm"; + reg = <0x0 0xfe6e0010 0x0 0x10>; + clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>; + clock-names = "pwm", "pclk"; + pinctrl-0 = <&pwm5_pins>; + pinctrl-names = "default"; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm6: pwm@fe6e0020 { + compatible = "rockchip,rk3568-pwm", "rockchip,rk3328-pwm"; + reg = <0x0 0xfe6e0020 0x0 0x10>; + clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>; + clock-names = "pwm", "pclk"; + pinctrl-0 = <&pwm6_pins>; + pinctrl-names = "default"; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm7: pwm@fe6e0030 { + compatible = "rockchip,rk3568-pwm", "rockchip,rk3328-pwm"; + reg = <0x0 0xfe6e0030 0x0 0x10>; + clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>; + clock-names = "pwm", "pclk"; + pinctrl-0 = <&pwm7_pins>; + pinctrl-names = "default"; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm8: pwm@fe6f0000 { + compatible = "rockchip,rk3568-pwm", "rockchip,rk3328-pwm"; + reg = <0x0 0xfe6f0000 0x0 0x10>; + clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>; + clock-names = "pwm", "pclk"; + pinctrl-0 = <&pwm8m0_pins>; + pinctrl-names = "default"; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm9: pwm@fe6f0010 { + compatible = "rockchip,rk3568-pwm", "rockchip,rk3328-pwm"; + reg = <0x0 0xfe6f0010 0x0 0x10>; + clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>; + clock-names = "pwm", "pclk"; + pinctrl-0 = <&pwm9m0_pins>; + pinctrl-names = "default"; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm10: pwm@fe6f0020 { + compatible = "rockchip,rk3568-pwm", "rockchip,rk3328-pwm"; + reg = <0x0 0xfe6f0020 0x0 0x10>; + clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>; + clock-names = "pwm", "pclk"; + pinctrl-0 = <&pwm10m0_pins>; + pinctrl-names = "default"; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm11: pwm@fe6f0030 { + compatible = "rockchip,rk3568-pwm", "rockchip,rk3328-pwm"; + reg = <0x0 0xfe6f0030 0x0 0x10>; + clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>; + clock-names = "pwm", "pclk"; + pinctrl-0 = <&pwm11m0_pins>; + pinctrl-names = "default"; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm12: pwm@fe700000 { + compatible = "rockchip,rk3568-pwm", "rockchip,rk3328-pwm"; + reg = <0x0 0xfe700000 0x0 0x10>; + clocks = <&cru CLK_PWM3>, <&cru PCLK_PWM3>; + clock-names = "pwm", "pclk"; + pinctrl-0 = <&pwm12m0_pins>; + pinctrl-names = "default"; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm13: pwm@fe700010 { + compatible = "rockchip,rk3568-pwm", "rockchip,rk3328-pwm"; + reg = <0x0 0xfe700010 0x0 0x10>; + clocks = <&cru CLK_PWM3>, <&cru PCLK_PWM3>; + clock-names = "pwm", "pclk"; + pinctrl-0 = <&pwm13m0_pins>; + pinctrl-names = "default"; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm14: pwm@fe700020 { + compatible = "rockchip,rk3568-pwm", "rockchip,rk3328-pwm"; + reg = <0x0 0xfe700020 0x0 0x10>; + clocks = <&cru CLK_PWM3>, <&cru PCLK_PWM3>; + clock-names = "pwm", "pclk"; + pinctrl-0 = <&pwm14m0_pins>; + pinctrl-names = "default"; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm15: pwm@fe700030 { + compatible = "rockchip,rk3568-pwm", "rockchip,rk3328-pwm"; + reg = <0x0 0xfe700030 0x0 0x10>; + clocks = <&cru CLK_PWM3>, <&cru PCLK_PWM3>; + clock-names = "pwm", "pclk"; + pinctrl-0 = <&pwm15m0_pins>; + pinctrl-names = "default"; + #pwm-cells = <3>; + status = "disabled"; + }; + + combphy1: phy@fe830000 { + compatible = "rockchip,rk3568-naneng-combphy"; + reg = <0x0 0xfe830000 0x0 0x100>; + clocks = <&pmucru CLK_PCIEPHY1_REF>, + <&cru PCLK_PIPEPHY1>, + <&cru PCLK_PIPE>; + clock-names = "ref", "apb", "pipe"; + assigned-clocks = <&pmucru CLK_PCIEPHY1_REF>; + assigned-clock-rates = <100000000>; + resets = <&cru SRST_PIPEPHY1>; + rockchip,pipe-grf = <&pipegrf>; + rockchip,pipe-phy-grf = <&pipe_phy_grf1>; + #phy-cells = <1>; + status = "disabled"; + }; + + combphy2: phy@fe840000 { + compatible = "rockchip,rk3568-naneng-combphy"; + reg = <0x0 0xfe840000 0x0 0x100>; + clocks = <&pmucru CLK_PCIEPHY2_REF>, + <&cru PCLK_PIPEPHY2>, + <&cru PCLK_PIPE>; + clock-names = "ref", "apb", "pipe"; + assigned-clocks = <&pmucru CLK_PCIEPHY2_REF>; + assigned-clock-rates = <100000000>; + resets = <&cru SRST_PIPEPHY2>; + rockchip,pipe-grf = <&pipegrf>; + rockchip,pipe-phy-grf = <&pipe_phy_grf2>; + #phy-cells = <1>; + status = "disabled"; + }; + + usb2phy0: usb2phy@fe8a0000 { + compatible = "rockchip,rk3568-usb2phy"; + reg = <0x0 0xfe8a0000 0x0 0x10000>; + clocks = <&pmucru CLK_USBPHY0_REF>; + clock-names = "phyclk"; + clock-output-names = "clk_usbphy0_480m"; + interrupts = ; + rockchip,usbgrf = <&usb2phy0_grf>; + #clock-cells = <0>; + status = "disabled"; + + usb2phy0_host: host-port { + #phy-cells = <0>; + status = "disabled"; + }; + + usb2phy0_otg: otg-port { + #phy-cells = <0>; + status = "disabled"; + }; + }; + + usb2phy1: usb2phy@fe8b0000 { + compatible = "rockchip,rk3568-usb2phy"; + reg = <0x0 0xfe8b0000 0x0 0x10000>; + clocks = <&pmucru CLK_USBPHY1_REF>; + clock-names = "phyclk"; + clock-output-names = "clk_usbphy1_480m"; + interrupts = ; + rockchip,usbgrf = <&usb2phy1_grf>; + #clock-cells = <0>; + status = "disabled"; + + usb2phy1_host: host-port { + #phy-cells = <0>; + status = "disabled"; + }; + + usb2phy1_otg: otg-port { + #phy-cells = <0>; + status = "disabled"; + }; + }; + + pinctrl: pinctrl { + compatible = "rockchip,rk3568-pinctrl"; + rockchip,grf = <&grf>; + rockchip,pmu = <&pmugrf>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + gpio0: gpio@fdd60000 { + compatible = "rockchip,gpio-bank"; + reg = <0x0 0xfdd60000 0x0 0x100>; + interrupts = ; + clocks = <&pmucru PCLK_GPIO0>, <&pmucru DBCLK_GPIO0>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio1: gpio@fe740000 { + compatible = "rockchip,gpio-bank"; + reg = <0x0 0xfe740000 0x0 0x100>; + interrupts = ; + clocks = <&cru PCLK_GPIO1>, <&cru DBCLK_GPIO1>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio2: gpio@fe750000 { + compatible = "rockchip,gpio-bank"; + reg = <0x0 0xfe750000 0x0 0x100>; + interrupts = ; + clocks = <&cru PCLK_GPIO2>, <&cru DBCLK_GPIO2>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio3: gpio@fe760000 { + compatible = "rockchip,gpio-bank"; + reg = <0x0 0xfe760000 0x0 0x100>; + interrupts = ; + clocks = <&cru PCLK_GPIO3>, <&cru DBCLK_GPIO3>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio4: gpio@fe770000 { + compatible = "rockchip,gpio-bank"; + reg = <0x0 0xfe770000 0x0 0x100>; + interrupts = ; + clocks = <&cru PCLK_GPIO4>, <&cru DBCLK_GPIO4>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; +}; + +#include "rk3568-pinctrl.dtsi" diff --git a/target/linux/rockchip/files-5.15/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/target/linux/rockchip/files-5.15/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c new file mode 100644 index 000000000..0b49fed16 --- /dev/null +++ b/target/linux/rockchip/files-5.15/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -0,0 +1,2706 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2020 Rockchip Electronics Co., Ltd. + * Author: Andy Yan + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "rockchip_drm_drv.h" +#include "rockchip_drm_gem.h" +#include "rockchip_drm_fb.h" +#include "rockchip_drm_vop2.h" + +/* + * VOP2 architecture + * + +----------+ +-------------+ +-----------+ + | Cluster | | Sel 1 from 6| | 1 from 3 | + | window0 | | Layer0 | | RGB | + +----------+ +-------------+ +---------------+ +-------------+ +-----------+ + +----------+ +-------------+ |N from 6 layers| | | + | Cluster | | Sel 1 from 6| | Overlay0 +--->| Video Port0 | +-----------+ + | window1 | | Layer1 | | | | | | 1 from 3 | + +----------+ +-------------+ +---------------+ +-------------+ | LVDS | + +----------+ +-------------+ +-----------+ + | Esmart | | Sel 1 from 6| + | window0 | | Layer2 | +---------------+ +-------------+ +-----------+ + +----------+ +-------------+ |N from 6 Layers| | | +--> | 1 from 3 | + +----------+ +-------------+ --------> | Overlay1 +--->| Video Port1 | | MIPI | + | Esmart | | Sel 1 from 6| --------> | | | | +-----------+ + | Window1 | | Layer3 | +---------------+ +-------------+ + +----------+ +-------------+ +-----------+ + +----------+ +-------------+ | 1 from 3 | + | Smart | | Sel 1 from 6| +---------------+ +-------------+ | HDMI | + | Window0 | | Layer4 | |N from 6 Layers| | | +-----------+ + +----------+ +-------------+ | Overlay2 +--->| Video Port2 | + +----------+ +-------------+ | | | | +-----------+ + | Smart | | Sel 1 from 6| +---------------+ +-------------+ | 1 from 3 | + | Window1 | | Layer5 | | eDP | + +----------+ +-------------+ +-----------+ + * + */ + +enum vop2_data_format { + VOP2_FMT_ARGB8888 = 0, + VOP2_FMT_RGB888, + VOP2_FMT_RGB565, + VOP2_FMT_XRGB101010, + VOP2_FMT_YUV420SP, + VOP2_FMT_YUV422SP, + VOP2_FMT_YUV444SP, + VOP2_FMT_YUYV422 = 8, + VOP2_FMT_YUYV420, + VOP2_FMT_VYUY422, + VOP2_FMT_VYUY420, + VOP2_FMT_YUV420SP_TILE_8x4 = 0x10, + VOP2_FMT_YUV420SP_TILE_16x2, + VOP2_FMT_YUV422SP_TILE_8x4, + VOP2_FMT_YUV422SP_TILE_16x2, + VOP2_FMT_YUV420SP_10, + VOP2_FMT_YUV422SP_10, + VOP2_FMT_YUV444SP_10, +}; + +enum vop2_afbc_format { + VOP2_AFBC_FMT_RGB565, + VOP2_AFBC_FMT_ARGB2101010 = 2, + VOP2_AFBC_FMT_YUV420_10BIT, + VOP2_AFBC_FMT_RGB888, + VOP2_AFBC_FMT_ARGB8888, + VOP2_AFBC_FMT_YUV420 = 9, + VOP2_AFBC_FMT_YUV422 = 0xb, + VOP2_AFBC_FMT_YUV422_10BIT = 0xe, + VOP2_AFBC_FMT_INVALID = -1, +}; + +union vop2_alpha_ctrl { + u32 val; + struct { + /* [0:1] */ + u32 color_mode:1; + u32 alpha_mode:1; + /* [2:3] */ + u32 blend_mode:2; + u32 alpha_cal_mode:1; + /* [5:7] */ + u32 factor_mode:3; + /* [8:9] */ + u32 alpha_en:1; + u32 src_dst_swap:1; + u32 reserved:6; + /* [16:23] */ + u32 glb_alpha:8; + } bits; +}; + +struct vop2_alpha { + union vop2_alpha_ctrl src_color_ctrl; + union vop2_alpha_ctrl dst_color_ctrl; + union vop2_alpha_ctrl src_alpha_ctrl; + union vop2_alpha_ctrl dst_alpha_ctrl; +}; + +struct vop2_alpha_config { + bool src_premulti_en; + bool dst_premulti_en; + bool src_pixel_alpha_en; + bool dst_pixel_alpha_en; + u16 src_glb_alpha_value; + u16 dst_glb_alpha_value; +}; + +struct vop2_win { + struct vop2 *vop2; + struct drm_plane base; + const struct vop2_win_data *data; + struct regmap_field *reg[VOP2_WIN_MAX_REG]; + + /** + * @win_id: graphic window id, a cluster may be split into two + * graphics windows. + */ + u8 win_id; + u8 delay; + u32 offset; + + enum drm_plane_type type; +}; + +struct vop2_video_port { + struct drm_crtc crtc; + struct vop2 *vop2; + struct clk *dclk; + unsigned int id; + const struct vop2_video_port_regs *regs; + const struct vop2_video_port_data *data; + + struct completion dsp_hold_completion; + + /** + * @win_mask: Bitmask of windows attached to the video port; + */ + u32 win_mask; + + struct vop2_win *primary_plane; + struct drm_pending_vblank_event *event; + + unsigned int nlayers; +}; + +struct vop2 { + struct device *dev; + struct drm_device *drm; + struct vop2_video_port vps[ROCKCHIP_MAX_CRTC]; + + const struct vop2_data *data; + /* + * Number of windows that are registered as plane, may be less than the + * total number of hardware windows. + */ + u32 registered_num_wins; + + void __iomem *regs; + struct regmap *map; + + struct regmap *grf; + + /* physical map length of vop2 register */ + u32 len; + + void __iomem *lut_regs; + + /* protects crtc enable/disable */ + struct mutex vop2_lock; + + int irq; + + /* + * Some global resources are shared between all video ports(crtcs), so + * we need a ref counter here. + */ + unsigned int enable_count; + struct clk *hclk; + struct clk *aclk; + + /* must be put at the end of the struct */ + struct vop2_win win[]; +}; + +static struct vop2_video_port *to_vop2_video_port(struct drm_crtc *crtc) +{ + return container_of(crtc, struct vop2_video_port, crtc); +} + +static struct vop2_win *to_vop2_win(struct drm_plane *p) +{ + return container_of(p, struct vop2_win, base); +} + +static void vop2_lock(struct vop2 *vop2) +{ + mutex_lock(&vop2->vop2_lock); +} + +static void vop2_unlock(struct vop2 *vop2) +{ + mutex_unlock(&vop2->vop2_lock); +} + +static void vop2_writel(struct vop2 *vop2, u32 offset, u32 v) +{ + regmap_write(vop2->map, offset, v); +} + +static void vop2_vp_write(struct vop2_video_port *vp, u32 offset, u32 v) +{ + regmap_write(vp->vop2->map, vp->data->offset + offset, v); +} + +static u32 vop2_readl(struct vop2 *vop2, u32 offset) +{ + u32 val; + + regmap_read(vop2->map, offset, &val); + + return val; +} + +static void vop2_win_write(const struct vop2_win *win, unsigned int reg, u32 v) +{ + regmap_field_write(win->reg[reg], v); +} + +static bool vop2_cluster_window(const struct vop2_win *win) +{ + return win->data->feature & WIN_FEATURE_CLUSTER; +} + +static void vop2_cfg_done(struct vop2_video_port *vp) +{ + struct vop2 *vop2 = vp->vop2; + + regmap_set_bits(vop2->map, RK3568_REG_CFG_DONE, + BIT(vp->id) | RK3568_REG_CFG_DONE__GLB_CFG_DONE_EN); +} + +static void vop2_win_disable(struct vop2_win *win) +{ + vop2_win_write(win, VOP2_WIN_ENABLE, 0); + + if (vop2_cluster_window(win)) + vop2_win_write(win, VOP2_WIN_CLUSTER_ENABLE, 0); +} + +static enum vop2_data_format vop2_convert_format(u32 format) +{ + switch (format) { + case DRM_FORMAT_XRGB8888: + case DRM_FORMAT_ARGB8888: + case DRM_FORMAT_XBGR8888: + case DRM_FORMAT_ABGR8888: + return VOP2_FMT_ARGB8888; + case DRM_FORMAT_RGB888: + case DRM_FORMAT_BGR888: + return VOP2_FMT_RGB888; + case DRM_FORMAT_RGB565: + case DRM_FORMAT_BGR565: + return VOP2_FMT_RGB565; + case DRM_FORMAT_NV12: + return VOP2_FMT_YUV420SP; + case DRM_FORMAT_NV16: + return VOP2_FMT_YUV422SP; + case DRM_FORMAT_NV24: + return VOP2_FMT_YUV444SP; + case DRM_FORMAT_YUYV: + case DRM_FORMAT_YVYU: + return VOP2_FMT_VYUY422; + case DRM_FORMAT_VYUY: + case DRM_FORMAT_UYVY: + return VOP2_FMT_YUYV422; + default: + DRM_ERROR("unsupported format[%08x]\n", format); + return -EINVAL; + } +} + +static enum vop2_afbc_format vop2_convert_afbc_format(u32 format) +{ + switch (format) { + case DRM_FORMAT_XRGB8888: + case DRM_FORMAT_ARGB8888: + case DRM_FORMAT_XBGR8888: + case DRM_FORMAT_ABGR8888: + return VOP2_AFBC_FMT_ARGB8888; + case DRM_FORMAT_RGB888: + case DRM_FORMAT_BGR888: + return VOP2_AFBC_FMT_RGB888; + case DRM_FORMAT_RGB565: + case DRM_FORMAT_BGR565: + return VOP2_AFBC_FMT_RGB565; + case DRM_FORMAT_NV12: + return VOP2_AFBC_FMT_YUV420; + case DRM_FORMAT_NV16: + return VOP2_AFBC_FMT_YUV422; + default: + return VOP2_AFBC_FMT_INVALID; + } + + return VOP2_AFBC_FMT_INVALID; +} + +static bool vop2_win_rb_swap(u32 format) +{ + switch (format) { + case DRM_FORMAT_XBGR8888: + case DRM_FORMAT_ABGR8888: + case DRM_FORMAT_BGR888: + case DRM_FORMAT_BGR565: + return true; + default: + return false; + } +} + +static bool vop2_afbc_rb_swap(u32 format) +{ + switch (format) { + case DRM_FORMAT_NV24: + return true; + default: + return false; + } +} + +static bool vop2_afbc_uv_swap(u32 format) +{ + switch (format) { + case DRM_FORMAT_NV12: + case DRM_FORMAT_NV16: + return true; + default: + return false; + } +} + +static bool vop2_win_uv_swap(u32 format) +{ + switch (format) { + case DRM_FORMAT_NV12: + case DRM_FORMAT_NV16: + case DRM_FORMAT_NV24: + return true; + default: + return false; + } +} + +static bool vop2_win_dither_up(u32 format) +{ + switch (format) { + case DRM_FORMAT_BGR565: + case DRM_FORMAT_RGB565: + return true; + default: + return false; + } +} + +static bool vop2_output_uv_swap(u32 bus_format, u32 output_mode) +{ + /* + * FIXME: + * + * There is no media type for YUV444 output, + * so when out_mode is AAAA or P888, assume output is YUV444 on + * yuv format. + * + * From H/W testing, YUV444 mode need a rb swap. + */ + if (bus_format == MEDIA_BUS_FMT_YVYU8_1X16 || + bus_format == MEDIA_BUS_FMT_VYUY8_1X16 || + bus_format == MEDIA_BUS_FMT_YVYU8_2X8 || + bus_format == MEDIA_BUS_FMT_VYUY8_2X8 || + ((bus_format == MEDIA_BUS_FMT_YUV8_1X24 || + bus_format == MEDIA_BUS_FMT_YUV10_1X30) && + (output_mode == ROCKCHIP_OUT_MODE_AAAA || + output_mode == ROCKCHIP_OUT_MODE_P888))) + return true; + else + return false; +} + +static bool is_yuv_output(u32 bus_format) +{ + switch (bus_format) { + case MEDIA_BUS_FMT_YUV8_1X24: + case MEDIA_BUS_FMT_YUV10_1X30: + case MEDIA_BUS_FMT_UYYVYY8_0_5X24: + case MEDIA_BUS_FMT_UYYVYY10_0_5X30: + case MEDIA_BUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YVYU8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_VYUY8_2X8: + case MEDIA_BUS_FMT_YUYV8_1X16: + case MEDIA_BUS_FMT_YVYU8_1X16: + case MEDIA_BUS_FMT_UYVY8_1X16: + case MEDIA_BUS_FMT_VYUY8_1X16: + return true; + default: + return false; + } +} + +static bool rockchip_afbc(struct drm_plane *plane, u64 modifier) +{ + int i; + + if (modifier == DRM_FORMAT_MOD_LINEAR) + return false; + + for (i = 0 ; i < plane->modifier_count; i++) + if (plane->modifiers[i] == modifier) + return true; + + return false; +} + +static bool rockchip_vop2_mod_supported(struct drm_plane *plane, u32 format, + u64 modifier) +{ + struct vop2_win *win = to_vop2_win(plane); + struct vop2 *vop2 = win->vop2; + + if (modifier == DRM_FORMAT_MOD_INVALID) + return false; + + if (modifier == DRM_FORMAT_MOD_LINEAR) + return true; + + if (!rockchip_afbc(plane, modifier)) { + drm_err(vop2->drm, "Unsupported format modifier 0x%llx\n", + modifier); + + return false; + } + + return vop2_convert_afbc_format(format) >= 0; +} + +static u32 vop2_afbc_transform_offset(struct drm_plane_state *pstate, + bool afbc_half_block_en) +{ + struct drm_rect *src = &pstate->src; + struct drm_framebuffer *fb = pstate->fb; + u32 bpp = fb->format->cpp[0] * 8; + u32 vir_width = (fb->pitches[0] << 3) / bpp; + u32 width = drm_rect_width(src) >> 16; + u32 height = drm_rect_height(src) >> 16; + u32 act_xoffset = src->x1 >> 16; + u32 act_yoffset = src->y1 >> 16; + u32 align16_crop = 0; + u32 align64_crop = 0; + u32 height_tmp; + u8 tx, ty; + u8 bottom_crop_line_num = 0; + + /* 16 pixel align */ + if (height & 0xf) + align16_crop = 16 - (height & 0xf); + + height_tmp = height + align16_crop; + + /* 64 pixel align */ + if (height_tmp & 0x3f) + align64_crop = 64 - (height_tmp & 0x3f); + + bottom_crop_line_num = align16_crop + align64_crop; + + switch (pstate->rotation & + (DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y | + DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270)) { + case DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y: + tx = 16 - ((act_xoffset + width) & 0xf); + ty = bottom_crop_line_num - act_yoffset; + break; + case DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90: + tx = bottom_crop_line_num - act_yoffset; + ty = vir_width - width - act_xoffset; + break; + case DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_270: + tx = act_yoffset; + ty = act_xoffset; + break; + case DRM_MODE_REFLECT_X: + tx = 16 - ((act_xoffset + width) & 0xf); + ty = act_yoffset; + break; + case DRM_MODE_REFLECT_Y: + tx = act_xoffset; + ty = bottom_crop_line_num - act_yoffset; + break; + case DRM_MODE_ROTATE_90: + tx = bottom_crop_line_num - act_yoffset; + ty = act_xoffset; + break; + case DRM_MODE_ROTATE_270: + tx = act_yoffset; + ty = vir_width - width - act_xoffset; + break; + case 0: + tx = act_xoffset; + ty = act_yoffset; + break; + } + + if (afbc_half_block_en) + ty &= 0x7f; + +#define TRANSFORM_XOFFSET GENMASK(7, 0) +#define TRANSFORM_YOFFSET GENMASK(23, 16) + return FIELD_PREP(TRANSFORM_XOFFSET, tx) | + FIELD_PREP(TRANSFORM_YOFFSET, ty); +} + +/* + * A Cluster window has 2048 x 16 line buffer, which can + * works at 2048 x 16(Full) or 4096 x 8 (Half) mode. + * for Cluster_lb_mode register: + * 0: half mode, for plane input width range 2048 ~ 4096 + * 1: half mode, for cluster work at 2 * 2048 plane mode + * 2: half mode, for rotate_90/270 mode + * + */ +static int vop2_get_cluster_lb_mode(struct vop2_win *win, + struct drm_plane_state *pstate) +{ + if ((pstate->rotation & DRM_MODE_ROTATE_270) || + (pstate->rotation & DRM_MODE_ROTATE_90)) + return 2; + else + return 0; +} + +static u16 vop2_scale_factor(u32 src, u32 dst) +{ + u32 fac; + int shift; + + if (src == dst) + return 0; + + if (dst < 2) + return U16_MAX; + + if (src < 2) + return 0; + + if (src > dst) + shift = 12; + else + shift = 16; + + src--; + dst--; + + fac = DIV_ROUND_UP(src << shift, dst) - 1; + + if (fac > U16_MAX) + return U16_MAX; + + return fac; +} + +static void vop2_setup_scale(struct vop2 *vop2, const struct vop2_win *win, + u32 src_w, u32 src_h, u32 dst_w, + u32 dst_h, u32 pixel_format) +{ + const struct drm_format_info *info; + u16 hor_scl_mode, ver_scl_mode; + u16 hscl_filter_mode, vscl_filter_mode; + u8 gt2 = 0; + u8 gt4 = 0; + u32 val; + + info = drm_format_info(pixel_format); + + if (src_h >= (4 * dst_h)) { + gt4 = 1; + src_h >>= 2; + } else if (src_h >= (2 * dst_h)) { + gt2 = 1; + src_h >>= 1; + } + + hor_scl_mode = scl_get_scl_mode(src_w, dst_w); + ver_scl_mode = scl_get_scl_mode(src_h, dst_h); + + if (hor_scl_mode == SCALE_UP) + hscl_filter_mode = VOP2_SCALE_UP_BIC; + else + hscl_filter_mode = VOP2_SCALE_DOWN_BIL; + + if (ver_scl_mode == SCALE_UP) + vscl_filter_mode = VOP2_SCALE_UP_BIL; + else + vscl_filter_mode = VOP2_SCALE_DOWN_BIL; + + /* + * RK3568 VOP Esmart/Smart dsp_w should be even pixel + * at scale down mode + */ + if (!(win->data->feature & WIN_FEATURE_AFBDC)) { + if ((hor_scl_mode == SCALE_DOWN) && (dst_w & 0x1)) { + drm_dbg(vop2->drm, "%s dst_w[%d] should align as 2 pixel\n", + win->data->name, dst_w); + dst_w++; + } + } + + val = vop2_scale_factor(src_w, dst_w); + vop2_win_write(win, VOP2_WIN_SCALE_YRGB_X, val); + val = vop2_scale_factor(src_h, dst_h); + vop2_win_write(win, VOP2_WIN_SCALE_YRGB_Y, val); + + vop2_win_write(win, VOP2_WIN_VSD_YRGB_GT4, gt4); + vop2_win_write(win, VOP2_WIN_VSD_YRGB_GT2, gt2); + + vop2_win_write(win, VOP2_WIN_YRGB_HOR_SCL_MODE, hor_scl_mode); + vop2_win_write(win, VOP2_WIN_YRGB_VER_SCL_MODE, ver_scl_mode); + + if (vop2_cluster_window(win)) + return; + + vop2_win_write(win, VOP2_WIN_YRGB_HSCL_FILTER_MODE, hscl_filter_mode); + vop2_win_write(win, VOP2_WIN_YRGB_VSCL_FILTER_MODE, vscl_filter_mode); + + if (info->is_yuv) { + src_w /= info->hsub; + src_h /= info->vsub; + + gt4 = 0; + gt2 = 0; + + if (src_h >= (4 * dst_h)) { + gt4 = 1; + src_h >>= 2; + } else if (src_h >= (2 * dst_h)) { + gt2 = 1; + src_h >>= 1; + } + + hor_scl_mode = scl_get_scl_mode(src_w, dst_w); + ver_scl_mode = scl_get_scl_mode(src_h, dst_h); + + val = vop2_scale_factor(src_w, dst_w); + vop2_win_write(win, VOP2_WIN_SCALE_CBCR_X, val); + + val = vop2_scale_factor(src_h, dst_h); + vop2_win_write(win, VOP2_WIN_SCALE_CBCR_Y, val); + + vop2_win_write(win, VOP2_WIN_VSD_CBCR_GT4, gt4); + vop2_win_write(win, VOP2_WIN_VSD_CBCR_GT2, gt2); + vop2_win_write(win, VOP2_WIN_CBCR_HOR_SCL_MODE, hor_scl_mode); + vop2_win_write(win, VOP2_WIN_CBCR_VER_SCL_MODE, ver_scl_mode); + vop2_win_write(win, VOP2_WIN_CBCR_HSCL_FILTER_MODE, hscl_filter_mode); + vop2_win_write(win, VOP2_WIN_CBCR_VSCL_FILTER_MODE, vscl_filter_mode); + } +} + +static int vop2_convert_csc_mode(int csc_mode) +{ + switch (csc_mode) { + case V4L2_COLORSPACE_SMPTE170M: + case V4L2_COLORSPACE_470_SYSTEM_M: + case V4L2_COLORSPACE_470_SYSTEM_BG: + return CSC_BT601L; + case V4L2_COLORSPACE_REC709: + case V4L2_COLORSPACE_SMPTE240M: + case V4L2_COLORSPACE_DEFAULT: + return CSC_BT709L; + case V4L2_COLORSPACE_JPEG: + return CSC_BT601F; + case V4L2_COLORSPACE_BT2020: + return CSC_BT2020; + default: + return CSC_BT709L; + } +} + +/* + * colorspace path: + * Input Win csc Output + * 1. YUV(2020) --> Y2R->2020To709->R2Y --> YUV_OUTPUT(601/709) + * RGB --> R2Y __/ + * + * 2. YUV(2020) --> bypasss --> YUV_OUTPUT(2020) + * RGB --> 709To2020->R2Y __/ + * + * 3. YUV(2020) --> Y2R->2020To709 --> RGB_OUTPUT(709) + * RGB --> R2Y __/ + * + * 4. YUV(601/709)-> Y2R->709To2020->R2Y --> YUV_OUTPUT(2020) + * RGB --> 709To2020->R2Y __/ + * + * 5. YUV(601/709)-> bypass --> YUV_OUTPUT(709) + * RGB --> R2Y __/ + * + * 6. YUV(601/709)-> bypass --> YUV_OUTPUT(601) + * RGB --> R2Y(601) __/ + * + * 7. YUV --> Y2R(709) --> RGB_OUTPUT(709) + * RGB --> bypass __/ + * + * 8. RGB --> 709To2020->R2Y --> YUV_OUTPUT(2020) + * + * 9. RGB --> R2Y(709) --> YUV_OUTPUT(709) + * + * 10. RGB --> R2Y(601) --> YUV_OUTPUT(601) + * + * 11. RGB --> bypass --> RGB_OUTPUT(709) + */ + +static void vop2_setup_csc_mode(struct vop2_video_port *vp, + struct vop2_win *win, + struct drm_plane_state *pstate) +{ + struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(vp->crtc.state); + int is_input_yuv = pstate->fb->format->is_yuv; + int is_output_yuv = is_yuv_output(vcstate->bus_format); + int input_csc = V4L2_COLORSPACE_DEFAULT; + int output_csc = vcstate->color_space; + bool r2y_en, y2r_en; + int csc_mode; + + if (is_input_yuv && !is_output_yuv) { + y2r_en = true; + r2y_en = false; + csc_mode = vop2_convert_csc_mode(input_csc); + } else if (!is_input_yuv && is_output_yuv) { + y2r_en = false; + r2y_en = true; + csc_mode = vop2_convert_csc_mode(output_csc); + } else { + y2r_en = false; + r2y_en = false; + csc_mode = false; + } + + vop2_win_write(win, VOP2_WIN_Y2R_EN, y2r_en); + vop2_win_write(win, VOP2_WIN_R2Y_EN, r2y_en); + vop2_win_write(win, VOP2_WIN_CSC_MODE, csc_mode); +} + +static void vop2_crtc_enable_irq(struct vop2_video_port *vp, u32 irq) +{ + struct vop2 *vop2 = vp->vop2; + + vop2_writel(vop2, RK3568_VP_INT_CLR(vp->id), irq << 16 | irq); + vop2_writel(vop2, RK3568_VP_INT_EN(vp->id), irq << 16 | irq); +} + +static void vop2_crtc_disable_irq(struct vop2_video_port *vp, u32 irq) +{ + struct vop2 *vop2 = vp->vop2; + + vop2_writel(vop2, RK3568_VP_INT_EN(vp->id), irq << 16); +} + +static int vop2_core_clks_prepare_enable(struct vop2 *vop2) +{ + int ret; + + ret = clk_prepare_enable(vop2->hclk); + if (ret < 0) { + drm_err(vop2->drm, "failed to enable hclk - %d\n", ret); + return ret; + } + + ret = clk_prepare_enable(vop2->aclk); + if (ret < 0) { + drm_err(vop2->drm, "failed to enable aclk - %d\n", ret); + goto err; + } + + return 0; +err: + clk_disable_unprepare(vop2->hclk); + + return ret; +} + +static void vop2_enable(struct vop2 *vop2) +{ + int ret; + + ret = pm_runtime_get_sync(vop2->dev); + if (ret < 0) { + drm_err(vop2->drm, "failed to get pm runtime: %d\n", ret); + return; + } + + ret = vop2_core_clks_prepare_enable(vop2); + if (ret) { + pm_runtime_put_sync(vop2->dev); + return; + } + + ret = rockchip_drm_dma_attach_device(vop2->drm, vop2->dev); + if (ret) { + drm_err(vop2->drm, "failed to attach dma mapping, %d\n", ret); + return; + } + + if (vop2->data->soc_id == 3566) + vop2_writel(vop2, RK3568_OTP_WIN_EN, 1); + + vop2_writel(vop2, RK3568_REG_CFG_DONE, RK3568_REG_CFG_DONE__GLB_CFG_DONE_EN); + + /* + * Disable auto gating, this is a workaround to + * avoid display image shift when a window enabled. + */ + regmap_clear_bits(vop2->map, RK3568_SYS_AUTO_GATING_CTRL, + RK3568_SYS_AUTO_GATING_CTRL__AUTO_GATING_EN); + + vop2_writel(vop2, RK3568_SYS0_INT_CLR, + VOP2_INT_BUS_ERRPR << 16 | VOP2_INT_BUS_ERRPR); + vop2_writel(vop2, RK3568_SYS0_INT_EN, + VOP2_INT_BUS_ERRPR << 16 | VOP2_INT_BUS_ERRPR); + vop2_writel(vop2, RK3568_SYS1_INT_CLR, + VOP2_INT_BUS_ERRPR << 16 | VOP2_INT_BUS_ERRPR); + vop2_writel(vop2, RK3568_SYS1_INT_EN, + VOP2_INT_BUS_ERRPR << 16 | VOP2_INT_BUS_ERRPR); +} + +static void vop2_disable(struct vop2 *vop2) +{ + rockchip_drm_dma_detach_device(vop2->drm, vop2->dev); + + pm_runtime_put_sync(vop2->dev); + + clk_disable_unprepare(vop2->aclk); + clk_disable_unprepare(vop2->hclk); +} + +static void vop2_crtc_atomic_disable(struct drm_crtc *crtc, + struct drm_atomic_state *state) +{ + struct vop2_video_port *vp = to_vop2_video_port(crtc); + struct vop2 *vop2 = vp->vop2; + int ret; + + vop2_lock(vop2); + + drm_crtc_vblank_off(crtc); + + /* + * Vop standby will take effect at end of current frame, + * if dsp hold valid irq happen, it means standby complete. + * + * we must wait standby complete when we want to disable aclk, + * if not, memory bus maybe dead. + */ + reinit_completion(&vp->dsp_hold_completion); + + vop2_crtc_enable_irq(vp, VP_INT_DSP_HOLD_VALID); + + vop2_vp_write(vp, RK3568_VP_DSP_CTRL, RK3568_VP_DSP_CTRL__STANDBY); + + ret = wait_for_completion_timeout(&vp->dsp_hold_completion, + msecs_to_jiffies(50)); + if (!ret) + drm_info(vop2->drm, "wait for vp%d dsp_hold timeout\n", vp->id); + + vop2_crtc_disable_irq(vp, VP_INT_DSP_HOLD_VALID); + + clk_disable_unprepare(vp->dclk); + + vop2->enable_count--; + + if (!vop2->enable_count) + vop2_disable(vop2); + + vop2_unlock(vop2); + + if (crtc->state->event && !crtc->state->active) { + spin_lock_irq(&crtc->dev->event_lock); + drm_crtc_send_vblank_event(crtc, crtc->state->event); + spin_unlock_irq(&crtc->dev->event_lock); + + crtc->state->event = NULL; + } +} + +static int vop2_plane_atomic_check(struct drm_plane *plane, + struct drm_atomic_state *astate) +{ + struct drm_plane_state *pstate = drm_atomic_get_new_plane_state(astate, plane); + struct drm_framebuffer *fb = pstate->fb; + struct drm_crtc *crtc = pstate->crtc; + struct drm_crtc_state *cstate; + struct vop2_video_port *vp; + struct vop2 *vop2; + const struct vop2_data *vop2_data; + struct drm_rect *dest = &pstate->dst; + struct drm_rect *src = &pstate->src; + int min_scale = FRAC_16_16(1, 8); + int max_scale = FRAC_16_16(8, 1); + int format; + int ret; + + if (!crtc) + return 0; + + vp = to_vop2_video_port(crtc); + vop2 = vp->vop2; + vop2_data = vop2->data; + + cstate = drm_atomic_get_existing_crtc_state(pstate->state, crtc); + if (WARN_ON(!cstate)) + return -EINVAL; + + ret = drm_atomic_helper_check_plane_state(pstate, cstate, + min_scale, max_scale, + true, true); + if (ret) + return ret; + + if (!pstate->visible) + return 0; + + format = vop2_convert_format(fb->format->format); + if (format < 0) + return format; + + if (drm_rect_width(src) >> 16 < 4 || drm_rect_height(src) >> 16 < 4 || + drm_rect_width(dest) < 4 || drm_rect_width(dest) < 4) { + drm_err(vop2->drm, "Invalid size: %dx%d->%dx%d, min size is 4x4\n", + drm_rect_width(src) >> 16, drm_rect_height(src) >> 16, + drm_rect_width(dest), drm_rect_height(dest)); + pstate->visible = false; + return 0; + } + + if (drm_rect_width(src) >> 16 > vop2_data->max_input.width || + drm_rect_height(src) >> 16 > vop2_data->max_input.height) { + drm_err(vop2->drm, "Invalid source: %dx%d. max input: %dx%d\n", + drm_rect_width(src) >> 16, + drm_rect_height(src) >> 16, + vop2_data->max_input.width, + vop2_data->max_input.height); + return -EINVAL; + } + + /* + * Src.x1 can be odd when do clip, but yuv plane start point + * need align with 2 pixel. + */ + if (fb->format->is_yuv && ((pstate->src.x1 >> 16) % 2)) { + drm_err(vop2->drm, "Invalid Source: Yuv format not support odd xpos\n"); + return -EINVAL; + } + + return 0; +} + +static void vop2_plane_atomic_disable(struct drm_plane *plane, + struct drm_atomic_state *state) +{ + struct drm_plane_state *old_pstate = drm_atomic_get_old_plane_state(state, plane); + struct vop2_win *win = to_vop2_win(plane); + struct vop2 *vop2 = win->vop2; + + drm_dbg(vop2->drm, "%s disable\n", win->data->name); + + if (!old_pstate->crtc) + return; + + vop2_win_disable(win); + vop2_win_write(win, VOP2_WIN_YUV_CLIP, 0); +} + +/* + * The color key is 10 bit, so all format should + * convert to 10 bit here. + */ +static void vop2_plane_setup_color_key(struct drm_plane *plane, u32 color_key) +{ + struct drm_plane_state *pstate = plane->state; + struct drm_framebuffer *fb = pstate->fb; + struct vop2_win *win = to_vop2_win(plane); + u32 color_key_en = 0; + u32 r = 0; + u32 g = 0; + u32 b = 0; + + if (!(color_key & VOP2_COLOR_KEY_MASK) || fb->format->is_yuv) { + vop2_win_write(win, VOP2_WIN_COLOR_KEY_EN, 0); + return; + } + + switch (fb->format->format) { + case DRM_FORMAT_RGB565: + case DRM_FORMAT_BGR565: + r = (color_key & 0xf800) >> 11; + g = (color_key & 0x7e0) >> 5; + b = (color_key & 0x1f); + r <<= 5; + g <<= 4; + b <<= 5; + color_key_en = 1; + break; + case DRM_FORMAT_XRGB8888: + case DRM_FORMAT_ARGB8888: + case DRM_FORMAT_XBGR8888: + case DRM_FORMAT_ABGR8888: + case DRM_FORMAT_RGB888: + case DRM_FORMAT_BGR888: + r = (color_key & 0xff0000) >> 16; + g = (color_key & 0xff00) >> 8; + b = (color_key & 0xff); + r <<= 2; + g <<= 2; + b <<= 2; + color_key_en = 1; + break; + } + + vop2_win_write(win, VOP2_WIN_COLOR_KEY_EN, color_key_en); + vop2_win_write(win, VOP2_WIN_COLOR_KEY, (r << 20) | (g << 10) | b); +} + +static void vop2_plane_atomic_update(struct drm_plane *plane, + struct drm_atomic_state *state) +{ + struct drm_plane_state *pstate = plane->state; + struct drm_crtc *crtc = pstate->crtc; + struct vop2_win *win = to_vop2_win(plane); + struct vop2_video_port *vp = to_vop2_video_port(crtc); + struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode; + struct vop2 *vop2 = win->vop2; + struct drm_framebuffer *fb = pstate->fb; + u32 bpp = fb->format->cpp[0] * 8; + u32 actual_w, actual_h, dsp_w, dsp_h; + u32 act_info, dsp_info; + u32 format; + u32 afbc_format; + u32 rb_swap; + u32 uv_swap; + struct drm_rect *src = &pstate->src; + struct drm_rect *dest = &pstate->dst; + u32 afbc_tile_num; + u32 transform_offset; + bool dither_up; + bool xmirror = pstate->rotation & DRM_MODE_REFLECT_X ? true : false; + bool ymirror = pstate->rotation & DRM_MODE_REFLECT_Y ? true : false; + bool rotate_270 = pstate->rotation & DRM_MODE_ROTATE_270; + bool rotate_90 = pstate->rotation & DRM_MODE_ROTATE_90; + struct rockchip_gem_object *rk_obj; + unsigned long offset; + bool afbc_en; + dma_addr_t yrgb_mst; + dma_addr_t uv_mst; + + /* + * can't update plane when vop2 is disabled. + */ + if (WARN_ON(!crtc)) + return; + + if (!pstate->visible) { + vop2_plane_atomic_disable(plane, state); + return; + } + + afbc_en = rockchip_afbc(plane, fb->modifier); + + offset = (src->x1 >> 16) * fb->format->cpp[0]; + + /* + * AFBC HDR_PTR must set to the zero offset of the framebuffer. + */ + if (afbc_en) + offset = 0; + else if (pstate->rotation & DRM_MODE_REFLECT_Y) + offset += ((src->y2 >> 16) - 1) * fb->pitches[0]; + else + offset += (src->y1 >> 16) * fb->pitches[0]; + + rk_obj = to_rockchip_obj(fb->obj[0]); + + yrgb_mst = rk_obj->dma_addr + offset + fb->offsets[0]; + if (fb->format->is_yuv) { + int hsub = fb->format->hsub; + int vsub = fb->format->vsub; + + offset = (src->x1 >> 16) * fb->format->cpp[1] / hsub; + offset += (src->y1 >> 16) * fb->pitches[1] / vsub; + + if ((pstate->rotation & DRM_MODE_REFLECT_Y) && !afbc_en) + offset += fb->pitches[1] * ((pstate->src_h >> 16) - 2) / vsub; + + rk_obj = to_rockchip_obj(fb->obj[0]); + uv_mst = rk_obj->dma_addr + offset + fb->offsets[1]; + } + + actual_w = drm_rect_width(src) >> 16; + actual_h = drm_rect_height(src) >> 16; + dsp_w = drm_rect_width(dest); + + if (dest->x1 + dsp_w > adjusted_mode->hdisplay) { + drm_err(vop2->drm, "vp%d %s dest->x1[%d] + dsp_w[%d] exceed mode hdisplay[%d]\n", + vp->id, win->data->name, dest->x1, dsp_w, adjusted_mode->hdisplay); + dsp_w = adjusted_mode->hdisplay - dest->x1; + if (dsp_w < 4) + dsp_w = 4; + actual_w = dsp_w * actual_w / drm_rect_width(dest); + } + + dsp_h = drm_rect_height(dest); + + if (dest->y1 + dsp_h > adjusted_mode->vdisplay) { + drm_err(vop2->drm, "vp%d %s dest->y1[%d] + dsp_h[%d] exceed mode vdisplay[%d]\n", + vp->id, win->data->name, dest->y1, dsp_h, adjusted_mode->vdisplay); + dsp_h = adjusted_mode->vdisplay - dest->y1; + if (dsp_h < 4) + dsp_h = 4; + actual_h = dsp_h * actual_h / drm_rect_height(dest); + } + + /* + * This is workaround solution for IC design: + * esmart can't support scale down when actual_w % 16 == 1. + */ + if (!(win->data->feature & WIN_FEATURE_AFBDC)) { + if (actual_w > dsp_w && (actual_w & 0xf) == 1) { + drm_err(vop2->drm, "vp%d %s act_w[%d] MODE 16 == 1\n", + vp->id, win->data->name, actual_w); + actual_w -= 1; + } + } + + if (afbc_en && actual_w % 4) { + drm_err(vop2->drm, "vp%d %s actual_w[%d] not 4 pixel aligned\n", + vp->id, win->data->name, actual_w); + actual_w = ALIGN_DOWN(actual_w, 4); + } + + act_info = (actual_h - 1) << 16 | ((actual_w - 1) & 0xffff); + dsp_info = (dsp_h - 1) << 16 | ((dsp_w - 1) & 0xffff); + + format = vop2_convert_format(fb->format->format); + + drm_dbg(vop2->drm, "vp%d update %s[%dx%d->%dx%d@%dx%d] fmt[%p4cc_%s] addr[%pad]\n", + vp->id, win->data->name, actual_w, actual_h, dsp_w, dsp_h, + dest->x1, dest->y1, + &fb->format->format, + afbc_en ? "AFBC" : "", &yrgb_mst); + + if (afbc_en) { + u32 stride; + + /* the afbc superblock is 16 x 16 */ + afbc_format = vop2_convert_afbc_format(fb->format->format); + + /* Enable color transform for YTR */ + if (fb->modifier & AFBC_FORMAT_MOD_YTR) + afbc_format |= (1 << 4); + + afbc_tile_num = ALIGN(actual_w, 16) >> 4; + + /* + * AFBC pic_vir_width is count by pixel, this is different + * with WIN_VIR_STRIDE. + */ + stride = (fb->pitches[0] << 3) / bpp; + if ((stride & 0x3f) && (xmirror || rotate_90 || rotate_270)) + drm_err(vop2->drm, "vp%d %s stride[%d] not 64 pixel aligened\n", + vp->id, win->data->name, stride); + + rb_swap = vop2_afbc_rb_swap(fb->format->format); + uv_swap = vop2_afbc_uv_swap(fb->format->format); + /* + * This is a workaround for crazy IC design, Cluster + * and Esmart/Smart use different format configuration map: + * YUV420_10BIT: 0x10 for Cluster, 0x14 for Esmart/Smart. + * + * This is one thing we can make the convert simple: + * AFBCD decode all the YUV data to YUV444. So we just + * set all the yuv 10 bit to YUV444_10. + */ + if (fb->format->is_yuv && bpp == 10) + format = VOP2_CLUSTER_YUV444_10; + + if (vop2_cluster_window(win)) + vop2_win_write(win, VOP2_WIN_AFBC_ENABLE, 1); + vop2_win_write(win, VOP2_WIN_AFBC_FORMAT, afbc_format); + vop2_win_write(win, VOP2_WIN_AFBC_RB_SWAP, rb_swap); + vop2_win_write(win, VOP2_WIN_AFBC_UV_SWAP, uv_swap); + vop2_win_write(win, VOP2_WIN_AFBC_AUTO_GATING_EN, 0); + vop2_win_write(win, VOP2_WIN_AFBC_BLOCK_SPLIT_EN, 0); + if (pstate->rotation & (DRM_MODE_ROTATE_270 | DRM_MODE_ROTATE_90)) { + vop2_win_write(win, VOP2_WIN_AFBC_HALF_BLOCK_EN, 0); + transform_offset = vop2_afbc_transform_offset(pstate, false); + } else { + vop2_win_write(win, VOP2_WIN_AFBC_HALF_BLOCK_EN, 1); + transform_offset = vop2_afbc_transform_offset(pstate, true); + } + vop2_win_write(win, VOP2_WIN_AFBC_HDR_PTR, yrgb_mst); + vop2_win_write(win, VOP2_WIN_AFBC_PIC_SIZE, act_info); + vop2_win_write(win, VOP2_WIN_AFBC_TRANSFORM_OFFSET, transform_offset); + vop2_win_write(win, VOP2_WIN_AFBC_PIC_OFFSET, ((src->x1 >> 16) | src->y1)); + vop2_win_write(win, VOP2_WIN_AFBC_DSP_OFFSET, (dest->x1 | (dest->y1 << 16))); + vop2_win_write(win, VOP2_WIN_AFBC_PIC_VIR_WIDTH, stride); + vop2_win_write(win, VOP2_WIN_AFBC_TILE_NUM, afbc_tile_num); + vop2_win_write(win, VOP2_WIN_XMIRROR, xmirror); + vop2_win_write(win, VOP2_WIN_AFBC_ROTATE_270, rotate_270); + vop2_win_write(win, VOP2_WIN_AFBC_ROTATE_90, rotate_90); + } else { + vop2_win_write(win, VOP2_WIN_YRGB_VIR, DIV_ROUND_UP(fb->pitches[0], 4)); + } + + vop2_win_write(win, VOP2_WIN_YMIRROR, ymirror); + + if (rotate_90 || rotate_270) { + act_info = swahw32(act_info); + actual_w = drm_rect_height(src) >> 16; + actual_h = drm_rect_width(src) >> 16; + } + + vop2_win_write(win, VOP2_WIN_FORMAT, format); + vop2_win_write(win, VOP2_WIN_YRGB_MST, yrgb_mst); + + rb_swap = vop2_win_rb_swap(fb->format->format); + vop2_win_write(win, VOP2_WIN_RB_SWAP, rb_swap); + if (!vop2_cluster_window(win)) { + uv_swap = vop2_win_uv_swap(fb->format->format); + vop2_win_write(win, VOP2_WIN_UV_SWAP, uv_swap); + } + + if (fb->format->is_yuv) { + vop2_win_write(win, VOP2_WIN_UV_VIR, DIV_ROUND_UP(fb->pitches[1], 4)); + vop2_win_write(win, VOP2_WIN_UV_MST, uv_mst); + } + + vop2_setup_scale(vop2, win, actual_w, actual_h, dsp_w, dsp_h, fb->format->format); + if (!vop2_cluster_window(win)) + vop2_plane_setup_color_key(plane, 0); + vop2_win_write(win, VOP2_WIN_ACT_INFO, act_info); + vop2_win_write(win, VOP2_WIN_DSP_INFO, dsp_info); + vop2_win_write(win, VOP2_WIN_DSP_ST, dest->y1 << 16 | (dest->x1 & 0xffff)); + + vop2_setup_csc_mode(vp, win, pstate); + + dither_up = vop2_win_dither_up(fb->format->format); + vop2_win_write(win, VOP2_WIN_DITHER_UP, dither_up); + + vop2_win_write(win, VOP2_WIN_ENABLE, 1); + + if (vop2_cluster_window(win)) { + int lb_mode = vop2_get_cluster_lb_mode(win, pstate); + + vop2_win_write(win, VOP2_WIN_CLUSTER_LB_MODE, lb_mode); + vop2_win_write(win, VOP2_WIN_CLUSTER_ENABLE, 1); + } +} + +static const struct drm_plane_helper_funcs vop2_plane_helper_funcs = { + .atomic_check = vop2_plane_atomic_check, + .atomic_update = vop2_plane_atomic_update, + .atomic_disable = vop2_plane_atomic_disable, +}; + +static const struct drm_plane_funcs vop2_plane_funcs = { + .update_plane = drm_atomic_helper_update_plane, + .disable_plane = drm_atomic_helper_disable_plane, + .destroy = drm_plane_cleanup, + .reset = drm_atomic_helper_plane_reset, + .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, + .format_mod_supported = rockchip_vop2_mod_supported, +}; + +static int vop2_crtc_enable_vblank(struct drm_crtc *crtc) +{ + struct vop2_video_port *vp = to_vop2_video_port(crtc); + + vop2_crtc_enable_irq(vp, VP_INT_FS_FIELD); + + return 0; +} + +static void vop2_crtc_disable_vblank(struct drm_crtc *crtc) +{ + struct vop2_video_port *vp = to_vop2_video_port(crtc); + + vop2_crtc_disable_irq(vp, VP_INT_FS_FIELD); +} + +static bool vop2_crtc_mode_fixup(struct drm_crtc *crtc, + const struct drm_display_mode *mode, + struct drm_display_mode *adj_mode) +{ + drm_mode_set_crtcinfo(adj_mode, CRTC_INTERLACE_HALVE_V | + CRTC_STEREO_DOUBLE); + + return true; +} + +static void vop2_dither_setup(struct drm_crtc *crtc, u32 *dsp_ctrl) +{ + struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state); + + switch (vcstate->bus_format) { + case MEDIA_BUS_FMT_RGB565_1X16: + *dsp_ctrl |= RK3568_VP_DSP_CTRL__DITHER_DOWN_EN; + break; + case MEDIA_BUS_FMT_RGB666_1X18: + case MEDIA_BUS_FMT_RGB666_1X24_CPADHI: + case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: + *dsp_ctrl |= RK3568_VP_DSP_CTRL__DITHER_DOWN_EN; + *dsp_ctrl |= RGB888_TO_RGB666; + break; + case MEDIA_BUS_FMT_YUV8_1X24: + case MEDIA_BUS_FMT_UYYVYY8_0_5X24: + *dsp_ctrl |= RK3568_VP_DSP_CTRL__PRE_DITHER_DOWN_EN; + break; + default: + break; + } + + if (vcstate->output_mode != ROCKCHIP_OUT_MODE_AAAA) + *dsp_ctrl |= RK3568_VP_DSP_CTRL__PRE_DITHER_DOWN_EN; + + *dsp_ctrl |= FIELD_PREP(RK3568_VP_DSP_CTRL__DITHER_DOWN_SEL, + DITHER_DOWN_ALLEGRO); +} + +static void vop2_post_config(struct drm_crtc *crtc) +{ + struct vop2_video_port *vp = to_vop2_video_port(crtc); + struct drm_display_mode *mode = &crtc->state->adjusted_mode; + u16 vtotal = mode->crtc_vtotal; + u16 hdisplay = mode->crtc_hdisplay; + u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start; + u16 vdisplay = mode->crtc_vdisplay; + u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start; + u32 left_margin = 100, right_margin = 100; + u32 top_margin = 100, bottom_margin = 100; + u16 hsize = hdisplay * (left_margin + right_margin) / 200; + u16 vsize = vdisplay * (top_margin + bottom_margin) / 200; + u16 hact_end, vact_end; + u32 val; + + vsize = rounddown(vsize, 2); + hsize = rounddown(hsize, 2); + hact_st += hdisplay * (100 - left_margin) / 200; + hact_end = hact_st + hsize; + val = hact_st << 16; + val |= hact_end; + vop2_vp_write(vp, RK3568_VP_POST_DSP_HACT_INFO, val); + vact_st += vdisplay * (100 - top_margin) / 200; + vact_end = vact_st + vsize; + val = vact_st << 16; + val |= vact_end; + vop2_vp_write(vp, RK3568_VP_POST_DSP_VACT_INFO, val); + val = scl_cal_scale2(vdisplay, vsize) << 16; + val |= scl_cal_scale2(hdisplay, hsize); + vop2_vp_write(vp, RK3568_VP_POST_SCL_FACTOR_YRGB, val); + + val = 0; + if (hdisplay != hsize) + val |= RK3568_VP_POST_SCL_CTRL__HSCALEDOWN; + if (vdisplay != vsize) + val |= RK3568_VP_POST_SCL_CTRL__VSCALEDOWN; + vop2_vp_write(vp, RK3568_VP_POST_SCL_CTRL, val); + + if (mode->flags & DRM_MODE_FLAG_INTERLACE) { + u16 vact_st_f1 = vtotal + vact_st + 1; + u16 vact_end_f1 = vact_st_f1 + vsize; + + val = vact_st_f1 << 16 | vact_end_f1; + vop2_vp_write(vp, RK3568_VP_POST_DSP_VACT_INFO_F1, val); + } + + vop2_vp_write(vp, RK3568_VP_DSP_BG, 0); +} + +static void rk3568_set_intf_mux(struct vop2_video_port *vp, int id, + u32 polflags) +{ + struct vop2 *vop2 = vp->vop2; + u32 die, dip; + + die = vop2_readl(vop2, RK3568_DSP_IF_EN); + dip = vop2_readl(vop2, RK3568_DSP_IF_POL); + + switch (id) { + case ROCKCHIP_VOP2_EP_RGB0: + die &= ~RK3568_SYS_DSP_INFACE_EN_RGB_MUX; + die |= RK3568_SYS_DSP_INFACE_EN_RGB | + FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_RGB_MUX, vp->id); + if (polflags & POLFLAG_DCLK_INV) + regmap_write(vop2->grf, RK3568_GRF_VO_CON1, BIT(3 + 16) | BIT(3)); + else + regmap_write(vop2->grf, RK3568_GRF_VO_CON1, BIT(3 + 16)); + break; + case ROCKCHIP_VOP2_EP_HDMI0: + die &= ~RK3568_SYS_DSP_INFACE_EN_HDMI_MUX; + die |= RK3568_SYS_DSP_INFACE_EN_HDMI | + FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_HDMI_MUX, vp->id); + break; + case ROCKCHIP_VOP2_EP_EDP0: + die &= ~RK3568_SYS_DSP_INFACE_EN_EDP_MUX; + die |= RK3568_SYS_DSP_INFACE_EN_EDP | + FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_EDP_MUX, vp->id); + break; + case ROCKCHIP_VOP2_EP_MIPI0: + die &= ~RK3568_SYS_DSP_INFACE_EN_MIPI0_MUX; + die |= RK3568_SYS_DSP_INFACE_EN_MIPI0 | + FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_MIPI0_MUX, vp->id); + dip &= ~RK3568_DSP_IF_POL__MIPI_PIN_POL; + dip |= FIELD_PREP(RK3568_DSP_IF_POL__MIPI_PIN_POL, polflags); + break; + case ROCKCHIP_VOP2_EP_MIPI1: + die &= ~RK3568_SYS_DSP_INFACE_EN_MIPI1_MUX; + die |= RK3568_SYS_DSP_INFACE_EN_MIPI1 | + FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_MIPI1_MUX, vp->id); + dip &= ~RK3568_DSP_IF_POL__MIPI_PIN_POL; + dip |= FIELD_PREP(RK3568_DSP_IF_POL__MIPI_PIN_POL, polflags); + break; + case ROCKCHIP_VOP2_EP_LVDS0: + die &= ~RK3568_SYS_DSP_INFACE_EN_LVDS0_MUX; + die |= RK3568_SYS_DSP_INFACE_EN_LVDS0 | + FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_LVDS0_MUX, vp->id); + dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL; + dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags); + break; + case ROCKCHIP_VOP2_EP_LVDS1: + die &= ~RK3568_SYS_DSP_INFACE_EN_LVDS1_MUX; + die |= RK3568_SYS_DSP_INFACE_EN_LVDS1 | + FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_LVDS1_MUX, vp->id); + dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL; + dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags); + break; + default: + drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id); + return; + }; + + dip |= RK3568_DSP_IF_POL__CFG_DONE_IMD; + + vop2_writel(vop2, RK3568_DSP_IF_EN, die); + vop2_writel(vop2, RK3568_DSP_IF_POL, dip); +} + +static int us_to_vertical_line(struct drm_display_mode *mode, int us) +{ + return us * mode->clock / mode->htotal / 1000; +} + +static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, + struct drm_atomic_state *state) +{ + struct vop2_video_port *vp = to_vop2_video_port(crtc); + struct vop2 *vop2 = vp->vop2; + const struct vop2_data *vop2_data = vop2->data; + const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id]; + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); + struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state); + struct drm_display_mode *mode = &crtc->state->adjusted_mode; + unsigned long clock = mode->crtc_clock * 1000; + u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; + u16 hdisplay = mode->crtc_hdisplay; + u16 htotal = mode->crtc_htotal; + u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start; + u16 hact_end = hact_st + hdisplay; + u16 vdisplay = mode->crtc_vdisplay; + u16 vtotal = mode->crtc_vtotal; + u16 vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start; + u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start; + u16 vact_end = vact_st + vdisplay; + u8 out_mode; + u32 dsp_ctrl = 0; + int act_end; + u32 val, polflags; + int ret; + struct drm_encoder *encoder; + + drm_dbg(vop2->drm, "Update mode to %dx%d%s%d, type: %d for vp%d\n", + hdisplay, vdisplay, mode->flags & DRM_MODE_FLAG_INTERLACE ? "i" : "p", + drm_mode_vrefresh(mode), vcstate->output_type, vp->id); + + vop2_lock(vop2); + + ret = clk_prepare_enable(vp->dclk); + if (ret < 0) { + drm_err(vop2->drm, "failed to enable dclk for video port%d - %d\n", + vp->id, ret); + return; + } + + if (!vop2->enable_count) + vop2_enable(vop2); + + vop2->enable_count++; + + vop2_crtc_enable_irq(vp, VP_INT_POST_BUF_EMPTY); + + polflags = 0; + if (vcstate->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE) + polflags |= POLFLAG_DCLK_INV; + if (mode->flags & DRM_MODE_FLAG_PHSYNC) + polflags |= BIT(HSYNC_POSITIVE); + if (mode->flags & DRM_MODE_FLAG_PVSYNC) + polflags |= BIT(VSYNC_POSITIVE); + + drm_for_each_encoder_mask(encoder, crtc->dev, crtc_state->encoder_mask) { + struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder); + + rk3568_set_intf_mux(vp, rkencoder->crtc_endpoint_id, polflags); + } + + if (vcstate->output_mode == ROCKCHIP_OUT_MODE_AAAA && + !(vp_data->feature & VOP_FEATURE_OUTPUT_10BIT)) + out_mode = ROCKCHIP_OUT_MODE_P888; + else + out_mode = vcstate->output_mode; + + dsp_ctrl |= FIELD_PREP(RK3568_VP_DSP_CTRL__OUT_MODE, out_mode); + + if (vop2_output_uv_swap(vcstate->bus_format, vcstate->output_mode)) + dsp_ctrl |= RK3568_VP_DSP_CTRL__DSP_RB_SWAP; + + if (is_yuv_output(vcstate->bus_format)) + dsp_ctrl |= RK3568_VP_DSP_CTRL__POST_DSP_OUT_R2Y; + + vop2_dither_setup(crtc, &dsp_ctrl); + + vop2_vp_write(vp, RK3568_VP_DSP_HTOTAL_HS_END, (htotal << 16) | hsync_len); + val = hact_st << 16; + val |= hact_end; + vop2_vp_write(vp, RK3568_VP_DSP_HACT_ST_END, val); + + val = vact_st << 16; + val |= vact_end; + vop2_vp_write(vp, RK3568_VP_DSP_VACT_ST_END, val); + + if (mode->flags & DRM_MODE_FLAG_INTERLACE) { + u16 vact_st_f1 = vtotal + vact_st + 1; + u16 vact_end_f1 = vact_st_f1 + vdisplay; + + val = vact_st_f1 << 16 | vact_end_f1; + vop2_vp_write(vp, RK3568_VP_DSP_VACT_ST_END_F1, val); + + val = vtotal << 16 | (vtotal + vsync_len); + vop2_vp_write(vp, RK3568_VP_DSP_VS_ST_END_F1, val); + dsp_ctrl |= RK3568_VP_DSP_CTRL__DSP_INTERLACE; + dsp_ctrl |= RK3568_VP_DSP_CTRL__DSP_FILED_POL; + dsp_ctrl |= RK3568_VP_DSP_CTRL__P2I_EN; + vtotal += vtotal + 1; + act_end = vact_end_f1; + } else { + act_end = vact_end; + } + + vop2_writel(vop2, RK3568_VP_LINE_FLAG(vp->id), + (act_end - us_to_vertical_line(mode, 0)) << 16 | act_end); + + vop2_vp_write(vp, RK3568_VP_DSP_VTOTAL_VS_END, vtotal << 16 | vsync_len); + + if (mode->flags & DRM_MODE_FLAG_DBLCLK) { + dsp_ctrl |= RK3568_VP_DSP_CTRL__CORE_DCLK_DIV; + clock *= 2; + } + + vop2_vp_write(vp, RK3568_VP_MIPI_CTRL, 0); + + clk_set_rate(vp->dclk, clock); + + vop2_post_config(crtc); + + vop2_cfg_done(vp); + + vop2_vp_write(vp, RK3568_VP_DSP_CTRL, dsp_ctrl); + + drm_crtc_vblank_on(crtc); + + vop2_unlock(vop2); +} + +static int vop2_crtc_atomic_check(struct drm_crtc *crtc, + struct drm_atomic_state *state) +{ + struct vop2_video_port *vp = to_vop2_video_port(crtc); + struct drm_plane *plane; + int nplanes = 0; + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); + + drm_atomic_crtc_state_for_each_plane(plane, crtc_state) + nplanes++; + + if (nplanes > vp->nlayers) + return -EINVAL; + + return 0; +} + +static bool is_opaque(u16 alpha) +{ + return (alpha >> 8) == 0xff; +} + +static void vop2_parse_alpha(struct vop2_alpha_config *alpha_config, + struct vop2_alpha *alpha) +{ + int src_glb_alpha_en = is_opaque(alpha_config->src_glb_alpha_value) ? 0 : 1; + int dst_glb_alpha_en = is_opaque(alpha_config->dst_glb_alpha_value) ? 0 : 1; + int src_color_mode = alpha_config->src_premulti_en ? + ALPHA_SRC_PRE_MUL : ALPHA_SRC_NO_PRE_MUL; + int dst_color_mode = alpha_config->dst_premulti_en ? + ALPHA_SRC_PRE_MUL : ALPHA_SRC_NO_PRE_MUL; + + alpha->src_color_ctrl.val = 0; + alpha->dst_color_ctrl.val = 0; + alpha->src_alpha_ctrl.val = 0; + alpha->dst_alpha_ctrl.val = 0; + + if (!alpha_config->src_pixel_alpha_en) + alpha->src_color_ctrl.bits.blend_mode = ALPHA_GLOBAL; + else if (alpha_config->src_pixel_alpha_en && !src_glb_alpha_en) + alpha->src_color_ctrl.bits.blend_mode = ALPHA_PER_PIX; + else + alpha->src_color_ctrl.bits.blend_mode = ALPHA_PER_PIX_GLOBAL; + + alpha->src_color_ctrl.bits.alpha_en = 1; + + if (alpha->src_color_ctrl.bits.blend_mode == ALPHA_GLOBAL) { + alpha->src_color_ctrl.bits.color_mode = src_color_mode; + alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_SRC_GLOBAL; + } else if (alpha->src_color_ctrl.bits.blend_mode == ALPHA_PER_PIX) { + alpha->src_color_ctrl.bits.color_mode = src_color_mode; + alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_ONE; + } else { + alpha->src_color_ctrl.bits.color_mode = ALPHA_SRC_PRE_MUL; + alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_SRC_GLOBAL; + } + alpha->src_color_ctrl.bits.glb_alpha = alpha_config->src_glb_alpha_value >> 8; + alpha->src_color_ctrl.bits.alpha_mode = ALPHA_STRAIGHT; + alpha->src_color_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION; + + alpha->dst_color_ctrl.bits.alpha_mode = ALPHA_STRAIGHT; + alpha->dst_color_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION; + alpha->dst_color_ctrl.bits.blend_mode = ALPHA_GLOBAL; + alpha->dst_color_ctrl.bits.glb_alpha = alpha_config->dst_glb_alpha_value >> 8; + alpha->dst_color_ctrl.bits.color_mode = dst_color_mode; + alpha->dst_color_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE; + + alpha->src_alpha_ctrl.bits.alpha_mode = ALPHA_STRAIGHT; + alpha->src_alpha_ctrl.bits.blend_mode = alpha->src_color_ctrl.bits.blend_mode; + alpha->src_alpha_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION; + alpha->src_alpha_ctrl.bits.factor_mode = ALPHA_ONE; + + alpha->dst_alpha_ctrl.bits.alpha_mode = ALPHA_STRAIGHT; + if (alpha_config->dst_pixel_alpha_en && !dst_glb_alpha_en) + alpha->dst_alpha_ctrl.bits.blend_mode = ALPHA_PER_PIX; + else + alpha->dst_alpha_ctrl.bits.blend_mode = ALPHA_PER_PIX_GLOBAL; + alpha->dst_alpha_ctrl.bits.alpha_cal_mode = ALPHA_NO_SATURATION; + alpha->dst_alpha_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE; +} + +static int vop2_find_start_mixer_id_for_vp(struct vop2 *vop2, u8 port_id) +{ + struct vop2_video_port *vp; + int used_layer = 0; + int i; + + for (i = 0; i < port_id; i++) { + vp = &vop2->vps[i]; + used_layer += hweight32(vp->win_mask); + } + + return used_layer; +} + +static void vop2_setup_cluster_alpha(struct vop2 *vop2, struct vop2_win *main_win) +{ + u32 offset = (main_win->data->phys_id * 0x10); + struct vop2_alpha_config alpha_config; + struct vop2_alpha alpha; + struct drm_plane_state *bottom_win_pstate; + bool src_pixel_alpha_en = false; + u16 src_glb_alpha_val, dst_glb_alpha_val; + bool premulti_en = false; + bool swap = false; + + /* At one win mode, win0 is dst/bottom win, and win1 is a all zero src/top win */ + bottom_win_pstate = main_win->base.state; + src_glb_alpha_val = 0; + dst_glb_alpha_val = main_win->base.state->alpha; + + if (!bottom_win_pstate->fb) + return; + + alpha_config.src_premulti_en = premulti_en; + alpha_config.dst_premulti_en = false; + alpha_config.src_pixel_alpha_en = src_pixel_alpha_en; + alpha_config.dst_pixel_alpha_en = true; /* alpha value need transfer to next mix */ + alpha_config.src_glb_alpha_value = src_glb_alpha_val; + alpha_config.dst_glb_alpha_value = dst_glb_alpha_val; + vop2_parse_alpha(&alpha_config, &alpha); + + alpha.src_color_ctrl.bits.src_dst_swap = swap; + vop2_writel(vop2, RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL + offset, + alpha.src_color_ctrl.val); + vop2_writel(vop2, RK3568_CLUSTER0_MIX_DST_COLOR_CTRL + offset, + alpha.dst_color_ctrl.val); + vop2_writel(vop2, RK3568_CLUSTER0_MIX_SRC_ALPHA_CTRL + offset, + alpha.src_alpha_ctrl.val); + vop2_writel(vop2, RK3568_CLUSTER0_MIX_DST_ALPHA_CTRL + offset, + alpha.dst_alpha_ctrl.val); +} + +static void vop2_setup_alpha(struct vop2_video_port *vp) +{ + struct vop2 *vop2 = vp->vop2; + struct drm_framebuffer *fb; + struct vop2_alpha_config alpha_config; + struct vop2_alpha alpha; + struct drm_plane *plane; + int pixel_alpha_en; + int premulti_en, gpremulti_en = 0; + int mixer_id; + u32 offset; + bool bottom_layer_alpha_en = false; + u32 dst_global_alpha = DRM_BLEND_ALPHA_OPAQUE; + + mixer_id = vop2_find_start_mixer_id_for_vp(vop2, vp->id); + alpha_config.dst_pixel_alpha_en = true; /* alpha value need transfer to next mix */ + + drm_atomic_crtc_for_each_plane(plane, &vp->crtc) { + struct vop2_win *win = to_vop2_win(plane); + + if (plane->state->normalized_zpos == 0 && + !is_opaque(plane->state->alpha) && + !vop2_cluster_window(win)) { + /* + * If bottom layer have global alpha effect [except cluster layer, + * because cluster have deal with bottom layer global alpha value + * at cluster mix], bottom layer mix need deal with global alpha. + */ + bottom_layer_alpha_en = true; + dst_global_alpha = plane->state->alpha; + } + } + + drm_atomic_crtc_for_each_plane(plane, &vp->crtc) { + struct vop2_win *win = to_vop2_win(plane); + int zpos = plane->state->normalized_zpos; + + if (plane->state->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI) + premulti_en = 1; + else + premulti_en = 0; + + plane = &win->base; + fb = plane->state->fb; + + pixel_alpha_en = fb->format->has_alpha; + + alpha_config.src_premulti_en = premulti_en; + + if (bottom_layer_alpha_en && zpos == 1) { + gpremulti_en = premulti_en; + /* Cd = Cs + (1 - As) * Cd * Agd */ + alpha_config.dst_premulti_en = false; + alpha_config.src_pixel_alpha_en = pixel_alpha_en; + alpha_config.src_glb_alpha_value = plane->state->alpha; + alpha_config.dst_glb_alpha_value = dst_global_alpha; + } else if (vop2_cluster_window(win)) { + /* Mix output data only have pixel alpha */ + alpha_config.dst_premulti_en = true; + alpha_config.src_pixel_alpha_en = true; + alpha_config.src_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE; + alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE; + } else { + /* Cd = Cs + (1 - As) * Cd */ + alpha_config.dst_premulti_en = true; + alpha_config.src_pixel_alpha_en = pixel_alpha_en; + alpha_config.src_glb_alpha_value = plane->state->alpha; + alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE; + } + + vop2_parse_alpha(&alpha_config, &alpha); + + offset = (mixer_id + zpos - 1) * 0x10; + vop2_writel(vop2, RK3568_MIX0_SRC_COLOR_CTRL + offset, + alpha.src_color_ctrl.val); + vop2_writel(vop2, RK3568_MIX0_DST_COLOR_CTRL + offset, + alpha.dst_color_ctrl.val); + vop2_writel(vop2, RK3568_MIX0_SRC_ALPHA_CTRL + offset, + alpha.src_alpha_ctrl.val); + vop2_writel(vop2, RK3568_MIX0_DST_ALPHA_CTRL + offset, + alpha.dst_alpha_ctrl.val); + } + + if (vp->id == 0) { + if (bottom_layer_alpha_en) { + /* Transfer pixel alpha to hdr mix */ + alpha_config.src_premulti_en = gpremulti_en; + alpha_config.dst_premulti_en = true; + alpha_config.src_pixel_alpha_en = true; + alpha_config.src_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE; + alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE; + vop2_parse_alpha(&alpha_config, &alpha); + + vop2_writel(vop2, RK3568_HDR0_SRC_COLOR_CTRL, + alpha.src_color_ctrl.val); + vop2_writel(vop2, RK3568_HDR0_DST_COLOR_CTRL, + alpha.dst_color_ctrl.val); + vop2_writel(vop2, RK3568_HDR0_SRC_ALPHA_CTRL, + alpha.src_alpha_ctrl.val); + vop2_writel(vop2, RK3568_HDR0_DST_ALPHA_CTRL, + alpha.dst_alpha_ctrl.val); + } else { + vop2_writel(vop2, RK3568_HDR0_SRC_COLOR_CTRL, 0); + } + } +} + +static void vop2_setup_layer_mixer(struct vop2_video_port *vp) +{ + struct vop2 *vop2 = vp->vop2; + struct drm_plane *plane; + u32 layer_sel = 0; + u32 port_sel; + unsigned int nlayer, ofs; + struct drm_display_mode *adjusted_mode; + u16 hsync_len; + u16 hdisplay; + u32 bg_dly; + u32 pre_scan_dly; + int i; + struct vop2_video_port *vp0 = &vop2->vps[0]; + struct vop2_video_port *vp1 = &vop2->vps[1]; + struct vop2_video_port *vp2 = &vop2->vps[2]; + + adjusted_mode = &vp->crtc.state->adjusted_mode; + hsync_len = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start; + hdisplay = adjusted_mode->crtc_hdisplay; + + bg_dly = vp->data->pre_scan_max_dly[3]; + vop2_writel(vop2, RK3568_VP_BG_MIX_CTRL(vp->id), + FIELD_PREP(RK3568_VP_BG_MIX_CTRL__BG_DLY, bg_dly)); + + pre_scan_dly = ((bg_dly + (hdisplay >> 1) - 1) << 16) | hsync_len; + vop2_vp_write(vp, RK3568_VP_PRE_SCAN_HTIMING, pre_scan_dly); + + vop2_writel(vop2, RK3568_OVL_CTRL, 0); + port_sel = vop2_readl(vop2, RK3568_OVL_PORT_SEL); + port_sel &= RK3568_OVL_PORT_SEL__SEL_PORT; + + if (vp0->nlayers) + port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT0_MUX, + vp0->nlayers - 1); + else + port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT0_MUX, 8); + + if (vp1->nlayers) + port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX, + (vp0->nlayers + vp1->nlayers - 1)); + else + port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX, 8); + + if (vp2->nlayers) + port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT2_MUX, + (vp2->nlayers + vp1->nlayers + vp0->nlayers - 1)); + else + port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX, 8); + + layer_sel = vop2_readl(vop2, RK3568_OVL_LAYER_SEL); + + ofs = 0; + for (i = 0; i < vp->id; i++) + ofs += vop2->vps[i].nlayers; + + nlayer = 0; + drm_atomic_crtc_for_each_plane(plane, &vp->crtc) { + struct vop2_win *win = to_vop2_win(plane); + + switch (win->data->phys_id) { + case ROCKCHIP_VOP2_CLUSTER0: + port_sel &= ~RK3568_OVL_PORT_SEL__CLUSTER0; + port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__CLUSTER0, vp->id); + break; + case ROCKCHIP_VOP2_CLUSTER1: + port_sel &= ~RK3568_OVL_PORT_SEL__CLUSTER1; + port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__CLUSTER1, vp->id); + break; + case ROCKCHIP_VOP2_ESMART0: + port_sel &= ~RK3568_OVL_PORT_SEL__ESMART0; + port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART0, vp->id); + break; + case ROCKCHIP_VOP2_ESMART1: + port_sel &= ~RK3568_OVL_PORT_SEL__ESMART1; + port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART1, vp->id); + break; + case ROCKCHIP_VOP2_SMART0: + port_sel &= ~RK3568_OVL_PORT_SEL__SMART0; + port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__SMART0, vp->id); + break; + case ROCKCHIP_VOP2_SMART1: + port_sel &= ~RK3568_OVL_PORT_SEL__SMART1; + port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__SMART1, vp->id); + break; + } + + layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(plane->state->normalized_zpos + ofs, + 0x7); + layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(plane->state->normalized_zpos + ofs, + win->data->layer_sel_id); + nlayer++; + } + + /* configure unused layers to 0x5 (reserved) */ + for (; nlayer < vp->nlayers; nlayer++) { + layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(nlayer + ofs, 0x7); + layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(nlayer + ofs, 5); + } + + vop2_writel(vop2, RK3568_OVL_LAYER_SEL, layer_sel); + vop2_writel(vop2, RK3568_OVL_PORT_SEL, port_sel); + vop2_writel(vop2, RK3568_OVL_CTRL, RK3568_OVL_CTRL__LAYERSEL_REGDONE_IMD); +} + +static void vop2_setup_dly_for_windows(struct vop2 *vop2) +{ + struct vop2_win *win; + int i = 0; + u32 cdly = 0, sdly = 0; + + for (i = 0; i < vop2->data->win_size; i++) { + u32 dly; + + win = &vop2->win[i]; + dly = win->delay; + + switch (win->data->phys_id) { + case ROCKCHIP_VOP2_CLUSTER0: + cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER0_0, dly); + cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER0_1, dly); + break; + case ROCKCHIP_VOP2_CLUSTER1: + cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER1_0, dly); + cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER1_1, dly); + break; + case ROCKCHIP_VOP2_ESMART0: + sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__ESMART0, dly); + break; + case ROCKCHIP_VOP2_ESMART1: + sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__ESMART1, dly); + break; + case ROCKCHIP_VOP2_SMART0: + sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART0, dly); + break; + case ROCKCHIP_VOP2_SMART1: + sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART1, dly); + break; + } + } + + vop2_writel(vop2, RK3568_CLUSTER_DLY_NUM, cdly); + vop2_writel(vop2, RK3568_SMART_DLY_NUM, sdly); +} + +static void vop2_crtc_atomic_begin(struct drm_crtc *crtc, + struct drm_atomic_state *state) +{ + struct vop2_video_port *vp = to_vop2_video_port(crtc); + struct vop2 *vop2 = vp->vop2; + struct drm_plane *plane; + + vp->win_mask = 0; + + drm_atomic_crtc_for_each_plane(plane, crtc) { + struct vop2_win *win = to_vop2_win(plane); + + win->delay = win->data->dly[VOP2_DLY_MODE_DEFAULT]; + + vp->win_mask |= BIT(win->data->phys_id); + + if (vop2_cluster_window(win)) + vop2_setup_cluster_alpha(vop2, win); + } + + if (!vp->win_mask) + return; + + vop2_setup_layer_mixer(vp); + vop2_setup_alpha(vp); + vop2_setup_dly_for_windows(vop2); +} + +static void vop2_crtc_atomic_flush(struct drm_crtc *crtc, + struct drm_atomic_state *state) +{ + struct vop2_video_port *vp = to_vop2_video_port(crtc); + + vop2_post_config(crtc); + + vop2_cfg_done(vp); + + spin_lock_irq(&crtc->dev->event_lock); + + if (crtc->state->event) { + WARN_ON(drm_crtc_vblank_get(crtc)); + vp->event = crtc->state->event; + crtc->state->event = NULL; + } + + spin_unlock_irq(&crtc->dev->event_lock); +} + +static const struct drm_crtc_helper_funcs vop2_crtc_helper_funcs = { + .mode_fixup = vop2_crtc_mode_fixup, + .atomic_check = vop2_crtc_atomic_check, + .atomic_begin = vop2_crtc_atomic_begin, + .atomic_flush = vop2_crtc_atomic_flush, + .atomic_enable = vop2_crtc_atomic_enable, + .atomic_disable = vop2_crtc_atomic_disable, +}; + +static void vop2_crtc_reset(struct drm_crtc *crtc) +{ + struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state); + + if (crtc->state) { + __drm_atomic_helper_crtc_destroy_state(crtc->state); + kfree(vcstate); + } + + vcstate = kzalloc(sizeof(*vcstate), GFP_KERNEL); + if (!vcstate) + return; + + crtc->state = &vcstate->base; + crtc->state->crtc = crtc; +} + +static struct drm_crtc_state *vop2_crtc_duplicate_state(struct drm_crtc *crtc) +{ + struct rockchip_crtc_state *vcstate, *old_vcstate; + + old_vcstate = to_rockchip_crtc_state(crtc->state); + + vcstate = kmemdup(old_vcstate, sizeof(*old_vcstate), GFP_KERNEL); + if (!vcstate) + return NULL; + + __drm_atomic_helper_crtc_duplicate_state(crtc, &vcstate->base); + + return &vcstate->base; +} + +static void vop2_crtc_destroy_state(struct drm_crtc *crtc, + struct drm_crtc_state *state) +{ + struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(state); + + __drm_atomic_helper_crtc_destroy_state(&vcstate->base); + kfree(vcstate); +} + +static const struct drm_crtc_funcs vop2_crtc_funcs = { + .set_config = drm_atomic_helper_set_config, + .page_flip = drm_atomic_helper_page_flip, + .destroy = drm_crtc_cleanup, + .reset = vop2_crtc_reset, + .atomic_duplicate_state = vop2_crtc_duplicate_state, + .atomic_destroy_state = vop2_crtc_destroy_state, + .enable_vblank = vop2_crtc_enable_vblank, + .disable_vblank = vop2_crtc_disable_vblank, +}; + +static irqreturn_t vop2_isr(int irq, void *data) +{ + struct vop2 *vop2 = data; + const struct vop2_data *vop2_data = vop2->data; + u32 axi_irqs[VOP2_SYS_AXI_BUS_NUM]; + int ret = IRQ_NONE; + int i; + + /* + * The irq is shared with the iommu. If the runtime-pm state of the + * vop2-device is disabled the irq has to be targeted at the iommu. + */ + if (!pm_runtime_get_if_in_use(vop2->dev)) + return IRQ_NONE; + + for (i = 0; i < vop2_data->nr_vps; i++) { + struct vop2_video_port *vp = &vop2->vps[i]; + struct drm_crtc *crtc = &vp->crtc; + u32 irqs; + + irqs = vop2_readl(vop2, RK3568_VP_INT_STATUS(vp->id)); + vop2_writel(vop2, RK3568_VP_INT_CLR(vp->id), irqs << 16 | irqs); + + if (irqs & VP_INT_DSP_HOLD_VALID) { + complete(&vp->dsp_hold_completion); + ret = IRQ_HANDLED; + } + + if (irqs & VP_INT_FS_FIELD) { + drm_crtc_handle_vblank(crtc); + spin_lock(&crtc->dev->event_lock); + if (vp->event) { + u32 val = vop2_readl(vop2, RK3568_REG_CFG_DONE); + + if (!(val & BIT(vp->id))) { + drm_crtc_send_vblank_event(crtc, vp->event); + vp->event = NULL; + drm_crtc_vblank_put(crtc); + } + } + spin_unlock(&crtc->dev->event_lock); + + ret = IRQ_HANDLED; + } + + if (irqs & VP_INT_POST_BUF_EMPTY) { + drm_err_ratelimited(vop2->drm, + "POST_BUF_EMPTY irq err at vp%d\n", + vp->id); + ret = IRQ_HANDLED; + } + } + + axi_irqs[0] = vop2_readl(vop2, RK3568_SYS0_INT_STATUS); + vop2_writel(vop2, RK3568_SYS0_INT_CLR, axi_irqs[0] << 16 | axi_irqs[0]); + axi_irqs[1] = vop2_readl(vop2, RK3568_SYS1_INT_STATUS); + vop2_writel(vop2, RK3568_SYS1_INT_CLR, axi_irqs[1] << 16 | axi_irqs[1]); + + for (i = 0; i < ARRAY_SIZE(axi_irqs); i++) { + if (axi_irqs[i] & VOP2_INT_BUS_ERRPR) { + drm_err_ratelimited(vop2->drm, "BUS_ERROR irq err\n"); + ret = IRQ_HANDLED; + } + } + + pm_runtime_put(vop2->dev); + + return ret; +} + +static int vop2_plane_init(struct vop2 *vop2, struct vop2_win *win, + unsigned long possible_crtcs) +{ + const struct vop2_win_data *win_data = win->data; + unsigned int blend_caps = BIT(DRM_MODE_BLEND_PIXEL_NONE) | + BIT(DRM_MODE_BLEND_PREMULTI) | + BIT(DRM_MODE_BLEND_COVERAGE); + int ret; + + ret = drm_universal_plane_init(vop2->drm, &win->base, possible_crtcs, + &vop2_plane_funcs, win_data->formats, + win_data->nformats, + win_data->format_modifiers, + win->type, win_data->name); + if (ret) { + drm_err(vop2->drm, "failed to initialize plane %d\n", ret); + return ret; + } + + drm_plane_helper_add(&win->base, &vop2_plane_helper_funcs); + + if (win->data->supported_rotations) + drm_plane_create_rotation_property(&win->base, DRM_MODE_ROTATE_0, + DRM_MODE_ROTATE_0 | + win->data->supported_rotations); + drm_plane_create_alpha_property(&win->base); + drm_plane_create_blend_mode_property(&win->base, blend_caps); + drm_plane_create_zpos_property(&win->base, win->win_id, 0, + vop2->registered_num_wins - 1); + + return 0; +} + +static struct vop2_video_port *find_vp_without_primary(struct vop2 *vop2) +{ + int i; + + for (i = 0; i < vop2->data->nr_vps; i++) { + struct vop2_video_port *vp = &vop2->vps[i]; + + if (!vp->crtc.port) + continue; + if (vp->primary_plane) + continue; + + return vp; + } + + return NULL; +} + +#define NR_LAYERS 6 + +static int vop2_create_crtc(struct vop2 *vop2) +{ + const struct vop2_data *vop2_data = vop2->data; + struct drm_device *drm = vop2->drm; + struct device *dev = vop2->dev; + struct drm_plane *plane; + struct device_node *port; + struct vop2_video_port *vp; + int i, nvp, nvps = 0; + int ret; + + for (i = 0; i < vop2_data->nr_vps; i++) { + const struct vop2_video_port_data *vp_data; + struct device_node *np; + char dclk_name[9]; + + vp_data = &vop2_data->vp[i]; + vp = &vop2->vps[i]; + vp->vop2 = vop2; + vp->id = vp_data->id; + vp->regs = vp_data->regs; + vp->data = vp_data; + + snprintf(dclk_name, sizeof(dclk_name), "dclk_vp%d", vp->id); + vp->dclk = devm_clk_get(vop2->dev, dclk_name); + if (IS_ERR(vp->dclk)) { + drm_err(vop2->drm, "failed to get %s\n", dclk_name); + return PTR_ERR(vp->dclk); + } + + np = of_graph_get_remote_node(dev->of_node, i, -1); + if (!np) { + drm_dbg(vop2->drm, "%s: No remote for vp%d\n", __func__, i); + continue; + } + of_node_put(np); + + port = of_graph_get_port_by_id(dev->of_node, i); + if (!port) { + drm_err(vop2->drm, "no port node found for video_port%d\n", i); + return -ENOENT; + } + + vp->crtc.port = port; + nvps++; + } + + nvp = 0; + for (i = 0; i < vop2->registered_num_wins; i++) { + struct vop2_win *win = &vop2->win[i]; + u32 possible_crtcs; + + if (vop2->data->soc_id == 3566) { + /* + * On RK3566 these windows don't have an independent + * framebuffer. They share the framebuffer with smart0, + * esmart0 and cluster0 respectively. + */ + switch (win->data->phys_id) { + case ROCKCHIP_VOP2_SMART1: + case ROCKCHIP_VOP2_ESMART1: + case ROCKCHIP_VOP2_CLUSTER1: + continue; + } + } + + if (win->type == DRM_PLANE_TYPE_PRIMARY) { + vp = find_vp_without_primary(vop2); + if (vp) { + possible_crtcs = BIT(nvp); + vp->primary_plane = win; + nvp++; + } else { + /* change the unused primary window to overlay window */ + win->type = DRM_PLANE_TYPE_OVERLAY; + } + } + + if (win->type == DRM_PLANE_TYPE_OVERLAY) + possible_crtcs = (1 << nvps) - 1; + + ret = vop2_plane_init(vop2, win, possible_crtcs); + if (ret) { + drm_err(vop2->drm, "failed to init plane %s: %d\n", + win->data->name, ret); + return ret; + } + } + + for (i = 0; i < vop2_data->nr_vps; i++) { + vp = &vop2->vps[i]; + + if (!vp->crtc.port) + continue; + + plane = &vp->primary_plane->base; + + ret = drm_crtc_init_with_planes(drm, &vp->crtc, plane, NULL, + &vop2_crtc_funcs, + "video_port%d", vp->id); + if (ret) { + drm_err(vop2->drm, "crtc init for video_port%d failed\n", i); + return ret; + } + + drm_crtc_helper_add(&vp->crtc, &vop2_crtc_helper_funcs); + + init_completion(&vp->dsp_hold_completion); + } + + /* + * On the VOP2 it's very hard to change the number of layers on a VP + * during runtime, so we distribute the layers equally over the used + * VPs + */ + for (i = 0; i < vop2->data->nr_vps; i++) { + struct vop2_video_port *vp = &vop2->vps[i]; + + if (vp->crtc.port) + vp->nlayers = NR_LAYERS / nvps; + } + + return 0; +} + +static void vop2_destroy_crtc(struct drm_crtc *crtc) +{ + of_node_put(crtc->port); + + /* + * Destroy CRTC after vop2_plane_destroy() since vop2_disable_plane() + * references the CRTC. + */ + drm_crtc_cleanup(crtc); +} + +static struct reg_field vop2_cluster_regs[VOP2_WIN_MAX_REG] = { + [VOP2_WIN_ENABLE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 0, 0), + [VOP2_WIN_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 1, 5), + [VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 14, 14), + [VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 18, 18), + [VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_ACT_INFO, 0, 31), + [VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_INFO, 0, 31), + [VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_ST, 0, 31), + [VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_CLUSTER_WIN_YRGB_MST, 0, 31), + [VOP2_WIN_UV_MST] = REG_FIELD(RK3568_CLUSTER_WIN_CBR_MST, 0, 31), + [VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 19, 19), + [VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 0, 15), + [VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 16, 31), + [VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 8, 8), + [VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 9, 9), + [VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 10, 11), + + /* Scale */ + [VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 0, 15), + [VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 16, 31), + [VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 14, 15), + [VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 12, 13), + [VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 2, 3), + [VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 28, 28), + [VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 29, 29), + + /* cluster regs */ + [VOP2_WIN_AFBC_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 1, 1), + [VOP2_WIN_CLUSTER_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 0, 0), + [VOP2_WIN_CLUSTER_LB_MODE] = REG_FIELD(RK3568_CLUSTER_CTRL, 4, 7), + + /* afbc regs */ + [VOP2_WIN_AFBC_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 2, 6), + [VOP2_WIN_AFBC_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 9, 9), + [VOP2_WIN_AFBC_UV_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 10, 10), + [VOP2_WIN_AFBC_AUTO_GATING_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_OUTPUT_CTRL, 4, 4), + [VOP2_WIN_AFBC_HALF_BLOCK_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 7, 7), + [VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 8, 8), + [VOP2_WIN_AFBC_HDR_PTR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_HDR_PTR, 0, 31), + [VOP2_WIN_AFBC_PIC_SIZE] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_SIZE, 0, 31), + [VOP2_WIN_AFBC_PIC_VIR_WIDTH] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 0, 15), + [VOP2_WIN_AFBC_TILE_NUM] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 16, 31), + [VOP2_WIN_AFBC_PIC_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_OFFSET, 0, 31), + [VOP2_WIN_AFBC_DSP_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_DSP_OFFSET, 0, 31), + [VOP2_WIN_AFBC_TRANSFORM_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_TRANSFORM_OFFSET, 0, 31), + [VOP2_WIN_AFBC_ROTATE_90] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 0, 0), + [VOP2_WIN_AFBC_ROTATE_270] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 1, 1), + [VOP2_WIN_XMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 2, 2), + [VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 3, 3), + [VOP2_WIN_UV_SWAP] = { .reg = 0xffffffff }, + [VOP2_WIN_COLOR_KEY] = { .reg = 0xffffffff }, + [VOP2_WIN_COLOR_KEY_EN] = { .reg = 0xffffffff }, + [VOP2_WIN_SCALE_CBCR_X] = { .reg = 0xffffffff }, + [VOP2_WIN_SCALE_CBCR_Y] = { .reg = 0xffffffff }, + [VOP2_WIN_YRGB_HSCL_FILTER_MODE] = { .reg = 0xffffffff }, + [VOP2_WIN_YRGB_VSCL_FILTER_MODE] = { .reg = 0xffffffff }, + [VOP2_WIN_CBCR_VER_SCL_MODE] = { .reg = 0xffffffff }, + [VOP2_WIN_CBCR_HSCL_FILTER_MODE] = { .reg = 0xffffffff }, + [VOP2_WIN_CBCR_HOR_SCL_MODE] = { .reg = 0xffffffff }, + [VOP2_WIN_CBCR_VSCL_FILTER_MODE] = { .reg = 0xffffffff }, + [VOP2_WIN_VSD_CBCR_GT2] = { .reg = 0xffffffff }, + [VOP2_WIN_VSD_CBCR_GT4] = { .reg = 0xffffffff }, +}; + +static int vop2_cluster_init(struct vop2_win *win) +{ + struct vop2 *vop2 = win->vop2; + struct reg_field *cluster_regs; + int ret, i; + + cluster_regs = kmemdup(vop2_cluster_regs, sizeof(vop2_cluster_regs), + GFP_KERNEL); + if (!cluster_regs) + return -ENOMEM; + + for (i = 0; i < ARRAY_SIZE(vop2_cluster_regs); i++) + if (cluster_regs[i].reg != 0xffffffff) + cluster_regs[i].reg += win->offset; + + ret = devm_regmap_field_bulk_alloc(vop2->dev, vop2->map, win->reg, + cluster_regs, + ARRAY_SIZE(vop2_cluster_regs)); + + kfree(cluster_regs); + + return ret; +}; + +static struct reg_field vop2_esmart_regs[VOP2_WIN_MAX_REG] = { + [VOP2_WIN_ENABLE] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 0, 0), + [VOP2_WIN_FORMAT] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 1, 5), + [VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 12, 12), + [VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 14, 14), + [VOP2_WIN_UV_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 16, 16), + [VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_SMART_REGION0_ACT_INFO, 0, 31), + [VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_SMART_REGION0_DSP_INFO, 0, 31), + [VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_SMART_REGION0_DSP_ST, 0, 28), + [VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_SMART_REGION0_YRGB_MST, 0, 31), + [VOP2_WIN_UV_MST] = REG_FIELD(RK3568_SMART_REGION0_CBR_MST, 0, 31), + [VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 17, 17), + [VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 0, 15), + [VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 16, 31), + [VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_SMART_CTRL0, 0, 0), + [VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_SMART_CTRL0, 1, 1), + [VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_SMART_CTRL0, 2, 3), + [VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_SMART_CTRL1, 31, 31), + [VOP2_WIN_COLOR_KEY] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 0, 29), + [VOP2_WIN_COLOR_KEY_EN] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 31, 31), + + /* Scale */ + [VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 0, 15), + [VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 16, 31), + [VOP2_WIN_SCALE_CBCR_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_CBR, 0, 15), + [VOP2_WIN_SCALE_CBCR_Y] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_CBR, 16, 31), + [VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 0, 1), + [VOP2_WIN_YRGB_HSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 2, 3), + [VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 4, 5), + [VOP2_WIN_YRGB_VSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 6, 7), + [VOP2_WIN_CBCR_HOR_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 8, 9), + [VOP2_WIN_CBCR_HSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 10, 11), + [VOP2_WIN_CBCR_VER_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 12, 13), + [VOP2_WIN_CBCR_VSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 14, 15), + [VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 16, 17), + [VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 8, 8), + [VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 9, 9), + [VOP2_WIN_VSD_CBCR_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 10, 10), + [VOP2_WIN_VSD_CBCR_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 11, 11), + [VOP2_WIN_XMIRROR] = { .reg = 0xffffffff }, + [VOP2_WIN_CLUSTER_ENABLE] = { .reg = 0xffffffff }, + [VOP2_WIN_AFBC_ENABLE] = { .reg = 0xffffffff }, + [VOP2_WIN_CLUSTER_LB_MODE] = { .reg = 0xffffffff }, + [VOP2_WIN_AFBC_FORMAT] = { .reg = 0xffffffff }, + [VOP2_WIN_AFBC_RB_SWAP] = { .reg = 0xffffffff }, + [VOP2_WIN_AFBC_UV_SWAP] = { .reg = 0xffffffff }, + [VOP2_WIN_AFBC_AUTO_GATING_EN] = { .reg = 0xffffffff }, + [VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = { .reg = 0xffffffff }, + [VOP2_WIN_AFBC_PIC_VIR_WIDTH] = { .reg = 0xffffffff }, + [VOP2_WIN_AFBC_TILE_NUM] = { .reg = 0xffffffff }, + [VOP2_WIN_AFBC_PIC_OFFSET] = { .reg = 0xffffffff }, + [VOP2_WIN_AFBC_PIC_SIZE] = { .reg = 0xffffffff }, + [VOP2_WIN_AFBC_DSP_OFFSET] = { .reg = 0xffffffff }, + [VOP2_WIN_AFBC_TRANSFORM_OFFSET] = { .reg = 0xffffffff }, + [VOP2_WIN_AFBC_HDR_PTR] = { .reg = 0xffffffff }, + [VOP2_WIN_AFBC_HALF_BLOCK_EN] = { .reg = 0xffffffff }, + [VOP2_WIN_AFBC_ROTATE_270] = { .reg = 0xffffffff }, + [VOP2_WIN_AFBC_ROTATE_90] = { .reg = 0xffffffff }, +}; + +static int vop2_esmart_init(struct vop2_win *win) +{ + struct vop2 *vop2 = win->vop2; + struct reg_field *esmart_regs; + int ret, i; + + esmart_regs = kmemdup(vop2_esmart_regs, sizeof(vop2_esmart_regs), + GFP_KERNEL); + if (!esmart_regs) + return -ENOMEM; + + for (i = 0; i < ARRAY_SIZE(vop2_esmart_regs); i++) + if (esmart_regs[i].reg != 0xffffffff) + esmart_regs[i].reg += win->offset; + + ret = devm_regmap_field_bulk_alloc(vop2->dev, vop2->map, win->reg, + esmart_regs, + ARRAY_SIZE(vop2_esmart_regs)); + + kfree(esmart_regs); + + return ret; +}; + +static int vop2_win_init(struct vop2 *vop2) +{ + const struct vop2_data *vop2_data = vop2->data; + struct vop2_win *win; + int i, ret; + + for (i = 0; i < vop2_data->win_size; i++) { + const struct vop2_win_data *win_data = &vop2_data->win[i]; + + win = &vop2->win[i]; + win->data = win_data; + win->type = win_data->type; + win->offset = win_data->base; + win->win_id = i; + win->vop2 = vop2; + if (vop2_cluster_window(win)) + ret = vop2_cluster_init(win); + else + ret = vop2_esmart_init(win); + if (ret) + return ret; + } + + vop2->registered_num_wins = vop2_data->win_size; + + return 0; +} + +/* + * The window registers are only updated when config done is written. + * Until that they read back the old value. As we read-modify-write + * these registers mark them as non-volatile. This makes sure we read + * the new values from the regmap register cache. + */ +static const struct regmap_range vop2_nonvolatile_range[] = { + regmap_reg_range(0x1000, 0x23ff), +}; + +static const struct regmap_access_table vop2_volatile_table = { + .no_ranges = vop2_nonvolatile_range, + .n_no_ranges = ARRAY_SIZE(vop2_nonvolatile_range), +}; + +static const struct regmap_config vop2_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .max_register = 0x3000, + .name = "vop2", + .volatile_table = &vop2_volatile_table, + .cache_type = REGCACHE_RBTREE, +}; + +static int vop2_bind(struct device *dev, struct device *master, void *data) +{ + struct platform_device *pdev = to_platform_device(dev); + const struct vop2_data *vop2_data; + struct drm_device *drm = data; + struct vop2 *vop2; + struct resource *res; + size_t alloc_size; + int ret; + + vop2_data = of_device_get_match_data(dev); + if (!vop2_data) + return -ENODEV; + + /* Allocate vop2 struct and its vop2_win array */ + alloc_size = sizeof(*vop2) + sizeof(*vop2->win) * vop2_data->win_size; + vop2 = devm_kzalloc(dev, alloc_size, GFP_KERNEL); + if (!vop2) + return -ENOMEM; + + vop2->dev = dev; + vop2->data = vop2_data; + vop2->drm = drm; + + dev_set_drvdata(dev, vop2); + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); + if (!res) { + drm_err(vop2->drm, "failed to get vop2 register byname\n"); + return -EINVAL; + } + + vop2->regs = devm_ioremap_resource(dev, res); + if (IS_ERR(vop2->regs)) + return PTR_ERR(vop2->regs); + vop2->len = resource_size(res); + + vop2->map = devm_regmap_init_mmio(dev, vop2->regs, &vop2_regmap_config); + + ret = vop2_win_init(vop2); + if (ret) + return ret; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gamma_lut"); + if (res) { + vop2->lut_regs = devm_ioremap_resource(dev, res); + if (IS_ERR(vop2->lut_regs)) + return PTR_ERR(vop2->lut_regs); + } + + vop2->grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf"); + + vop2->hclk = devm_clk_get(vop2->dev, "hclk"); + if (IS_ERR(vop2->hclk)) { + drm_err(vop2->drm, "failed to get hclk source\n"); + return PTR_ERR(vop2->hclk); + } + + vop2->aclk = devm_clk_get(vop2->dev, "aclk"); + if (IS_ERR(vop2->aclk)) { + drm_err(vop2->drm, "failed to get aclk source\n"); + return PTR_ERR(vop2->aclk); + } + + vop2->irq = platform_get_irq(pdev, 0); + if (vop2->irq < 0) { + drm_err(vop2->drm, "cannot find irq for vop2\n"); + return vop2->irq; + } + + mutex_init(&vop2->vop2_lock); + + ret = devm_request_irq(dev, vop2->irq, vop2_isr, IRQF_SHARED, dev_name(dev), vop2); + if (ret) + return ret; + + ret = vop2_create_crtc(vop2); + if (ret) + return ret; + + rockchip_drm_dma_init_device(vop2->drm, vop2->dev); + + pm_runtime_enable(&pdev->dev); + + return 0; +} + +static void vop2_unbind(struct device *dev, struct device *master, void *data) +{ + struct vop2 *vop2 = dev_get_drvdata(dev); + struct drm_device *drm = vop2->drm; + struct list_head *plane_list = &drm->mode_config.plane_list; + struct list_head *crtc_list = &drm->mode_config.crtc_list; + struct drm_crtc *crtc, *tmpc; + struct drm_plane *plane, *tmpp; + + pm_runtime_disable(dev); + + list_for_each_entry_safe(plane, tmpp, plane_list, head) + drm_plane_cleanup(plane); + + list_for_each_entry_safe(crtc, tmpc, crtc_list, head) + vop2_destroy_crtc(crtc); +} + +const struct component_ops vop2_component_ops = { + .bind = vop2_bind, + .unbind = vop2_unbind, +}; +EXPORT_SYMBOL_GPL(vop2_component_ops); diff --git a/target/linux/rockchip/files-5.15/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/target/linux/rockchip/files-5.15/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h new file mode 100644 index 000000000..c727093a0 --- /dev/null +++ b/target/linux/rockchip/files-5.15/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h @@ -0,0 +1,477 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd + * Author:Mark Yao + */ + +#ifndef _ROCKCHIP_DRM_VOP2_H +#define _ROCKCHIP_DRM_VOP2_H + +#include "rockchip_drm_vop.h" + +#include +#include + +#define VOP_FEATURE_OUTPUT_10BIT BIT(0) + +#define WIN_FEATURE_AFBDC BIT(0) +#define WIN_FEATURE_CLUSTER BIT(1) + +/* + * the delay number of a window in different mode. + */ +enum win_dly_mode { + VOP2_DLY_MODE_DEFAULT, /**< default mode */ + VOP2_DLY_MODE_HISO_S, /** HDR in SDR out mode, as a SDR window */ + VOP2_DLY_MODE_HIHO_H, /** HDR in HDR out mode, as a HDR window */ + VOP2_DLY_MODE_MAX, +}; + +struct vop_rect { + int width; + int height; +}; + +enum vop2_scale_up_mode { + VOP2_SCALE_UP_NRST_NBOR, + VOP2_SCALE_UP_BIL, + VOP2_SCALE_UP_BIC, +}; + +enum vop2_scale_down_mode { + VOP2_SCALE_DOWN_NRST_NBOR, + VOP2_SCALE_DOWN_BIL, + VOP2_SCALE_DOWN_AVG, +}; + +enum vop2_win_regs { + VOP2_WIN_ENABLE, + VOP2_WIN_FORMAT, + VOP2_WIN_CSC_MODE, + VOP2_WIN_XMIRROR, + VOP2_WIN_YMIRROR, + VOP2_WIN_RB_SWAP, + VOP2_WIN_UV_SWAP, + VOP2_WIN_ACT_INFO, + VOP2_WIN_DSP_INFO, + VOP2_WIN_DSP_ST, + VOP2_WIN_YRGB_MST, + VOP2_WIN_UV_MST, + VOP2_WIN_YRGB_VIR, + VOP2_WIN_UV_VIR, + VOP2_WIN_YUV_CLIP, + VOP2_WIN_Y2R_EN, + VOP2_WIN_R2Y_EN, + VOP2_WIN_COLOR_KEY, + VOP2_WIN_COLOR_KEY_EN, + VOP2_WIN_DITHER_UP, + + /* scale regs */ + VOP2_WIN_SCALE_YRGB_X, + VOP2_WIN_SCALE_YRGB_Y, + VOP2_WIN_SCALE_CBCR_X, + VOP2_WIN_SCALE_CBCR_Y, + VOP2_WIN_YRGB_HOR_SCL_MODE, + VOP2_WIN_YRGB_HSCL_FILTER_MODE, + VOP2_WIN_YRGB_VER_SCL_MODE, + VOP2_WIN_YRGB_VSCL_FILTER_MODE, + VOP2_WIN_CBCR_VER_SCL_MODE, + VOP2_WIN_CBCR_HSCL_FILTER_MODE, + VOP2_WIN_CBCR_HOR_SCL_MODE, + VOP2_WIN_CBCR_VSCL_FILTER_MODE, + VOP2_WIN_VSD_CBCR_GT2, + VOP2_WIN_VSD_CBCR_GT4, + VOP2_WIN_VSD_YRGB_GT2, + VOP2_WIN_VSD_YRGB_GT4, + VOP2_WIN_BIC_COE_SEL, + + /* cluster regs */ + VOP2_WIN_CLUSTER_ENABLE, + VOP2_WIN_AFBC_ENABLE, + VOP2_WIN_CLUSTER_LB_MODE, + + /* afbc regs */ + VOP2_WIN_AFBC_FORMAT, + VOP2_WIN_AFBC_RB_SWAP, + VOP2_WIN_AFBC_UV_SWAP, + VOP2_WIN_AFBC_AUTO_GATING_EN, + VOP2_WIN_AFBC_BLOCK_SPLIT_EN, + VOP2_WIN_AFBC_PIC_VIR_WIDTH, + VOP2_WIN_AFBC_TILE_NUM, + VOP2_WIN_AFBC_PIC_OFFSET, + VOP2_WIN_AFBC_PIC_SIZE, + VOP2_WIN_AFBC_DSP_OFFSET, + VOP2_WIN_AFBC_TRANSFORM_OFFSET, + VOP2_WIN_AFBC_HDR_PTR, + VOP2_WIN_AFBC_HALF_BLOCK_EN, + VOP2_WIN_AFBC_ROTATE_270, + VOP2_WIN_AFBC_ROTATE_90, + VOP2_WIN_MAX_REG, +}; + +struct vop2_win_data { + const char *name; + unsigned int phys_id; + + u32 base; + enum drm_plane_type type; + + u32 nformats; + const u32 *formats; + const uint64_t *format_modifiers; + const unsigned int supported_rotations; + + /** + * @layer_sel_id: defined by register OVERLAY_LAYER_SEL of VOP2 + */ + unsigned int layer_sel_id; + uint64_t feature; + + unsigned int max_upscale_factor; + unsigned int max_downscale_factor; + const u8 dly[VOP2_DLY_MODE_MAX]; +}; + +struct vop2_video_port_data { + unsigned int id; + u32 feature; + u16 gamma_lut_len; + u16 cubic_lut_len; + struct vop_rect max_output; + const u8 pre_scan_max_dly[4]; + const struct vop2_video_port_regs *regs; + unsigned int offset; +}; + +struct vop2_data { + u8 nr_vps; + const struct vop2_ctrl *ctrl; + const struct vop2_win_data *win; + const struct vop2_video_port_data *vp; + const struct vop_csc_table *csc_table; + struct vop_rect max_input; + struct vop_rect max_output; + + unsigned int win_size; + unsigned int soc_id; +}; + +/* interrupt define */ +#define FS_NEW_INTR BIT(4) +#define ADDR_SAME_INTR BIT(5) +#define LINE_FLAG1_INTR BIT(6) +#define WIN0_EMPTY_INTR BIT(7) +#define WIN1_EMPTY_INTR BIT(8) +#define WIN2_EMPTY_INTR BIT(9) +#define WIN3_EMPTY_INTR BIT(10) +#define HWC_EMPTY_INTR BIT(11) +#define POST_BUF_EMPTY_INTR BIT(12) +#define PWM_GEN_INTR BIT(13) +#define DMA_FINISH_INTR BIT(14) +#define FS_FIELD_INTR BIT(15) +#define FE_INTR BIT(16) +#define WB_UV_FIFO_FULL_INTR BIT(17) +#define WB_YRGB_FIFO_FULL_INTR BIT(18) +#define WB_COMPLETE_INTR BIT(19) + +/* + * display output interface supported by rockchip lcdc + */ +#define ROCKCHIP_OUT_MODE_P888 0 +#define ROCKCHIP_OUT_MODE_BT1120 0 +#define ROCKCHIP_OUT_MODE_P666 1 +#define ROCKCHIP_OUT_MODE_P565 2 +#define ROCKCHIP_OUT_MODE_BT656 5 +#define ROCKCHIP_OUT_MODE_S888 8 +#define ROCKCHIP_OUT_MODE_S888_DUMMY 12 +#define ROCKCHIP_OUT_MODE_YUV420 14 +/* for use special outface */ +#define ROCKCHIP_OUT_MODE_AAAA 15 + +enum vop_csc_format { + CSC_BT601L, + CSC_BT709L, + CSC_BT601F, + CSC_BT2020, +}; + +enum src_factor_mode { + SRC_FAC_ALPHA_ZERO, + SRC_FAC_ALPHA_ONE, + SRC_FAC_ALPHA_DST, + SRC_FAC_ALPHA_DST_INVERSE, + SRC_FAC_ALPHA_SRC, + SRC_FAC_ALPHA_SRC_GLOBAL, +}; + +enum dst_factor_mode { + DST_FAC_ALPHA_ZERO, + DST_FAC_ALPHA_ONE, + DST_FAC_ALPHA_SRC, + DST_FAC_ALPHA_SRC_INVERSE, + DST_FAC_ALPHA_DST, + DST_FAC_ALPHA_DST_GLOBAL, +}; + +#define RK3568_GRF_VO_CON1 0x0364 +/* System registers definition */ +#define RK3568_REG_CFG_DONE 0x000 +#define RK3568_VERSION_INFO 0x004 +#define RK3568_SYS_AUTO_GATING_CTRL 0x008 +#define RK3568_SYS_AXI_LUT_CTRL 0x024 +#define RK3568_DSP_IF_EN 0x028 +#define RK3568_DSP_IF_CTRL 0x02c +#define RK3568_DSP_IF_POL 0x030 +#define RK3568_WB_CTRL 0x40 +#define RK3568_WB_XSCAL_FACTOR 0x44 +#define RK3568_WB_YRGB_MST 0x48 +#define RK3568_WB_CBR_MST 0x4C +#define RK3568_OTP_WIN_EN 0x050 +#define RK3568_LUT_PORT_SEL 0x058 +#define RK3568_SYS_STATUS0 0x060 +#define RK3568_VP_LINE_FLAG(vp) (0x70 + (vp) * 0x4) +#define RK3568_SYS0_INT_EN 0x80 +#define RK3568_SYS0_INT_CLR 0x84 +#define RK3568_SYS0_INT_STATUS 0x88 +#define RK3568_SYS1_INT_EN 0x90 +#define RK3568_SYS1_INT_CLR 0x94 +#define RK3568_SYS1_INT_STATUS 0x98 +#define RK3568_VP_INT_EN(vp) (0xA0 + (vp) * 0x10) +#define RK3568_VP_INT_CLR(vp) (0xA4 + (vp) * 0x10) +#define RK3568_VP_INT_STATUS(vp) (0xA8 + (vp) * 0x10) +#define RK3568_VP_INT_RAW_STATUS(vp) (0xAC + (vp) * 0x10) + +/* Video Port registers definition */ +#define RK3568_VP_DSP_CTRL 0x00 +#define RK3568_VP_MIPI_CTRL 0x04 +#define RK3568_VP_COLOR_BAR_CTRL 0x08 +#define RK3568_VP_3D_LUT_CTRL 0x10 +#define RK3568_VP_3D_LUT_MST 0x20 +#define RK3568_VP_DSP_BG 0x2C +#define RK3568_VP_PRE_SCAN_HTIMING 0x30 +#define RK3568_VP_POST_DSP_HACT_INFO 0x34 +#define RK3568_VP_POST_DSP_VACT_INFO 0x38 +#define RK3568_VP_POST_SCL_FACTOR_YRGB 0x3C +#define RK3568_VP_POST_SCL_CTRL 0x40 +#define RK3568_VP_POST_DSP_VACT_INFO_F1 0x44 +#define RK3568_VP_DSP_HTOTAL_HS_END 0x48 +#define RK3568_VP_DSP_HACT_ST_END 0x4C +#define RK3568_VP_DSP_VTOTAL_VS_END 0x50 +#define RK3568_VP_DSP_VACT_ST_END 0x54 +#define RK3568_VP_DSP_VS_ST_END_F1 0x58 +#define RK3568_VP_DSP_VACT_ST_END_F1 0x5C +#define RK3568_VP_BCSH_CTRL 0x60 +#define RK3568_VP_BCSH_BCS 0x64 +#define RK3568_VP_BCSH_H 0x68 +#define RK3568_VP_BCSH_COLOR_BAR 0x6C + +/* Overlay registers definition */ +#define RK3568_OVL_CTRL 0x600 +#define RK3568_OVL_LAYER_SEL 0x604 +#define RK3568_OVL_PORT_SEL 0x608 +#define RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL 0x610 +#define RK3568_CLUSTER0_MIX_DST_COLOR_CTRL 0x614 +#define RK3568_CLUSTER0_MIX_SRC_ALPHA_CTRL 0x618 +#define RK3568_CLUSTER0_MIX_DST_ALPHA_CTRL 0x61C +#define RK3568_MIX0_SRC_COLOR_CTRL 0x650 +#define RK3568_MIX0_DST_COLOR_CTRL 0x654 +#define RK3568_MIX0_SRC_ALPHA_CTRL 0x658 +#define RK3568_MIX0_DST_ALPHA_CTRL 0x65C +#define RK3568_HDR0_SRC_COLOR_CTRL 0x6C0 +#define RK3568_HDR0_DST_COLOR_CTRL 0x6C4 +#define RK3568_HDR0_SRC_ALPHA_CTRL 0x6C8 +#define RK3568_HDR0_DST_ALPHA_CTRL 0x6CC +#define RK3568_VP_BG_MIX_CTRL(vp) (0x6E0 + (vp) * 4) +#define RK3568_CLUSTER_DLY_NUM 0x6F0 +#define RK3568_SMART_DLY_NUM 0x6F8 + +/* Cluster register definition, offset relative to window base */ +#define RK3568_CLUSTER_WIN_CTRL0 0x00 +#define RK3568_CLUSTER_WIN_CTRL1 0x04 +#define RK3568_CLUSTER_WIN_YRGB_MST 0x10 +#define RK3568_CLUSTER_WIN_CBR_MST 0x14 +#define RK3568_CLUSTER_WIN_VIR 0x18 +#define RK3568_CLUSTER_WIN_ACT_INFO 0x20 +#define RK3568_CLUSTER_WIN_DSP_INFO 0x24 +#define RK3568_CLUSTER_WIN_DSP_ST 0x28 +#define RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB 0x30 +#define RK3568_CLUSTER_WIN_AFBCD_TRANSFORM_OFFSET 0x3C +#define RK3568_CLUSTER_WIN_AFBCD_OUTPUT_CTRL 0x50 +#define RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE 0x54 +#define RK3568_CLUSTER_WIN_AFBCD_HDR_PTR 0x58 +#define RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH 0x5C +#define RK3568_CLUSTER_WIN_AFBCD_PIC_SIZE 0x60 +#define RK3568_CLUSTER_WIN_AFBCD_PIC_OFFSET 0x64 +#define RK3568_CLUSTER_WIN_AFBCD_DSP_OFFSET 0x68 +#define RK3568_CLUSTER_WIN_AFBCD_CTRL 0x6C + +#define RK3568_CLUSTER_CTRL 0x100 + +/* (E)smart register definition, offset relative to window base */ +#define RK3568_SMART_CTRL0 0x00 +#define RK3568_SMART_CTRL1 0x04 +#define RK3568_SMART_REGION0_CTRL 0x10 +#define RK3568_SMART_REGION0_YRGB_MST 0x14 +#define RK3568_SMART_REGION0_CBR_MST 0x18 +#define RK3568_SMART_REGION0_VIR 0x1C +#define RK3568_SMART_REGION0_ACT_INFO 0x20 +#define RK3568_SMART_REGION0_DSP_INFO 0x24 +#define RK3568_SMART_REGION0_DSP_ST 0x28 +#define RK3568_SMART_REGION0_SCL_CTRL 0x30 +#define RK3568_SMART_REGION0_SCL_FACTOR_YRGB 0x34 +#define RK3568_SMART_REGION0_SCL_FACTOR_CBR 0x38 +#define RK3568_SMART_REGION0_SCL_OFFSET 0x3C +#define RK3568_SMART_REGION1_CTRL 0x40 +#define RK3568_SMART_REGION1_YRGB_MST 0x44 +#define RK3568_SMART_REGION1_CBR_MST 0x48 +#define RK3568_SMART_REGION1_VIR 0x4C +#define RK3568_SMART_REGION1_ACT_INFO 0x50 +#define RK3568_SMART_REGION1_DSP_INFO 0x54 +#define RK3568_SMART_REGION1_DSP_ST 0x58 +#define RK3568_SMART_REGION1_SCL_CTRL 0x60 +#define RK3568_SMART_REGION1_SCL_FACTOR_YRGB 0x64 +#define RK3568_SMART_REGION1_SCL_FACTOR_CBR 0x68 +#define RK3568_SMART_REGION1_SCL_OFFSET 0x6C +#define RK3568_SMART_REGION2_CTRL 0x70 +#define RK3568_SMART_REGION2_YRGB_MST 0x74 +#define RK3568_SMART_REGION2_CBR_MST 0x78 +#define RK3568_SMART_REGION2_VIR 0x7C +#define RK3568_SMART_REGION2_ACT_INFO 0x80 +#define RK3568_SMART_REGION2_DSP_INFO 0x84 +#define RK3568_SMART_REGION2_DSP_ST 0x88 +#define RK3568_SMART_REGION2_SCL_CTRL 0x90 +#define RK3568_SMART_REGION2_SCL_FACTOR_YRGB 0x94 +#define RK3568_SMART_REGION2_SCL_FACTOR_CBR 0x98 +#define RK3568_SMART_REGION2_SCL_OFFSET 0x9C +#define RK3568_SMART_REGION3_CTRL 0xA0 +#define RK3568_SMART_REGION3_YRGB_MST 0xA4 +#define RK3568_SMART_REGION3_CBR_MST 0xA8 +#define RK3568_SMART_REGION3_VIR 0xAC +#define RK3568_SMART_REGION3_ACT_INFO 0xB0 +#define RK3568_SMART_REGION3_DSP_INFO 0xB4 +#define RK3568_SMART_REGION3_DSP_ST 0xB8 +#define RK3568_SMART_REGION3_SCL_CTRL 0xC0 +#define RK3568_SMART_REGION3_SCL_FACTOR_YRGB 0xC4 +#define RK3568_SMART_REGION3_SCL_FACTOR_CBR 0xC8 +#define RK3568_SMART_REGION3_SCL_OFFSET 0xCC +#define RK3568_SMART_COLOR_KEY_CTRL 0xD0 + +/* HDR register definition */ +#define RK3568_HDR_LUT_CTRL 0x2000 +#define RK3568_HDR_LUT_MST 0x2004 +#define RK3568_SDR2HDR_CTRL 0x2010 +#define RK3568_HDR2SDR_CTRL 0x2020 +#define RK3568_HDR2SDR_SRC_RANGE 0x2024 +#define RK3568_HDR2SDR_NORMFACEETF 0x2028 +#define RK3568_HDR2SDR_DST_RANGE 0x202C +#define RK3568_HDR2SDR_NORMFACCGAMMA 0x2030 +#define RK3568_HDR_EETF_OETF_Y0 0x203C +#define RK3568_HDR_SAT_Y0 0x20C0 +#define RK3568_HDR_EOTF_OETF_Y0 0x20F0 +#define RK3568_HDR_OETF_DX_POW1 0x2200 +#define RK3568_HDR_OETF_XN1 0x2300 + +#define RK3568_REG_CFG_DONE__GLB_CFG_DONE_EN BIT(15) + +#define RK3568_VP_DSP_CTRL__STANDBY BIT(31) +#define RK3568_VP_DSP_CTRL__DITHER_DOWN_MODE BIT(20) +#define RK3568_VP_DSP_CTRL__DITHER_DOWN_SEL GENMASK(19, 18) +#define RK3568_VP_DSP_CTRL__DITHER_DOWN_EN BIT(17) +#define RK3568_VP_DSP_CTRL__PRE_DITHER_DOWN_EN BIT(16) +#define RK3568_VP_DSP_CTRL__POST_DSP_OUT_R2Y BIT(15) +#define RK3568_VP_DSP_CTRL__DSP_RB_SWAP BIT(9) +#define RK3568_VP_DSP_CTRL__DSP_INTERLACE BIT(7) +#define RK3568_VP_DSP_CTRL__DSP_FILED_POL BIT(6) +#define RK3568_VP_DSP_CTRL__P2I_EN BIT(5) +#define RK3568_VP_DSP_CTRL__CORE_DCLK_DIV BIT(4) +#define RK3568_VP_DSP_CTRL__OUT_MODE GENMASK(3, 0) + +#define RK3568_VP_POST_SCL_CTRL__VSCALEDOWN BIT(1) +#define RK3568_VP_POST_SCL_CTRL__HSCALEDOWN BIT(0) + +#define RK3568_SYS_DSP_INFACE_EN_LVDS1_MUX GENMASK(26, 25) +#define RK3568_SYS_DSP_INFACE_EN_LVDS1 BIT(24) +#define RK3568_SYS_DSP_INFACE_EN_MIPI1_MUX GENMASK(22, 21) +#define RK3568_SYS_DSP_INFACE_EN_MIPI1 BIT(20) +#define RK3568_SYS_DSP_INFACE_EN_LVDS0_MUX GENMASK(19, 18) +#define RK3568_SYS_DSP_INFACE_EN_MIPI0_MUX GENMASK(17, 16) +#define RK3568_SYS_DSP_INFACE_EN_EDP_MUX GENMASK(15, 14) +#define RK3568_SYS_DSP_INFACE_EN_HDMI_MUX GENMASK(11, 10) +#define RK3568_SYS_DSP_INFACE_EN_RGB_MUX GENMASK(9, 8) +#define RK3568_SYS_DSP_INFACE_EN_LVDS0 BIT(5) +#define RK3568_SYS_DSP_INFACE_EN_MIPI0 BIT(4) +#define RK3568_SYS_DSP_INFACE_EN_EDP BIT(3) +#define RK3568_SYS_DSP_INFACE_EN_HDMI BIT(1) +#define RK3568_SYS_DSP_INFACE_EN_RGB BIT(0) + +#define RK3568_DSP_IF_POL__MIPI_PIN_POL GENMASK(19, 16) +#define RK3568_DSP_IF_POL__EDP_PIN_POL GENMASK(15, 12) +#define RK3568_DSP_IF_POL__HDMI_PIN_POL GENMASK(7, 4) +#define RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL GENMASK(3, 0) + +#define RK3568_VP0_MIPI_CTRL__DCLK_DIV2_PHASE_LOCK BIT(5) +#define RK3568_VP0_MIPI_CTRL__DCLK_DIV2 BIT(4) + +#define RK3568_SYS_AUTO_GATING_CTRL__AUTO_GATING_EN BIT(31) + +#define RK3568_DSP_IF_POL__CFG_DONE_IMD BIT(28) + +#define VOP2_SYS_AXI_BUS_NUM 2 + +#define VOP2_CLUSTER_YUV444_10 0x12 + +#define VOP2_COLOR_KEY_MASK BIT(31) + +#define RK3568_OVL_CTRL__LAYERSEL_REGDONE_IMD BIT(28) + +#define RK3568_VP_BG_MIX_CTRL__BG_DLY GENMASK(31, 24) + +#define RK3568_OVL_PORT_SEL__SEL_PORT GENMASK(31, 16) +#define RK3568_OVL_PORT_SEL__SMART1 GENMASK(31, 30) +#define RK3568_OVL_PORT_SEL__SMART0 GENMASK(29, 28) +#define RK3568_OVL_PORT_SEL__ESMART1 GENMASK(27, 26) +#define RK3568_OVL_PORT_SEL__ESMART0 GENMASK(25, 24) +#define RK3568_OVL_PORT_SEL__CLUSTER1 GENMASK(19, 18) +#define RK3568_OVL_PORT_SEL__CLUSTER0 GENMASK(17, 16) +#define RK3568_OVL_PORT_SET__PORT2_MUX GENMASK(11, 8) +#define RK3568_OVL_PORT_SET__PORT1_MUX GENMASK(7, 4) +#define RK3568_OVL_PORT_SET__PORT0_MUX GENMASK(3, 0) +#define RK3568_OVL_LAYER_SEL__LAYER(layer, x) ((x) << ((layer) * 4)) + +#define RK3568_CLUSTER_DLY_NUM__CLUSTER1_1 GENMASK(31, 24) +#define RK3568_CLUSTER_DLY_NUM__CLUSTER1_0 GENMASK(23, 16) +#define RK3568_CLUSTER_DLY_NUM__CLUSTER0_1 GENMASK(15, 8) +#define RK3568_CLUSTER_DLY_NUM__CLUSTER0_0 GENMASK(7, 0) + +#define RK3568_SMART_DLY_NUM__SMART1 GENMASK(31, 24) +#define RK3568_SMART_DLY_NUM__SMART0 GENMASK(23, 16) +#define RK3568_SMART_DLY_NUM__ESMART1 GENMASK(15, 8) +#define RK3568_SMART_DLY_NUM__ESMART0 GENMASK(7, 0) + +#define VP_INT_DSP_HOLD_VALID BIT(6) +#define VP_INT_FS_FIELD BIT(5) +#define VP_INT_POST_BUF_EMPTY BIT(4) +#define VP_INT_LINE_FLAG1 BIT(3) +#define VP_INT_LINE_FLAG0 BIT(2) +#define VOP2_INT_BUS_ERRPR BIT(1) +#define VP_INT_FS BIT(0) + +#define POLFLAG_DCLK_INV BIT(3) + +enum vop2_layer_phy_id { + ROCKCHIP_VOP2_CLUSTER0 = 0, + ROCKCHIP_VOP2_CLUSTER1, + ROCKCHIP_VOP2_ESMART0, + ROCKCHIP_VOP2_ESMART1, + ROCKCHIP_VOP2_SMART0, + ROCKCHIP_VOP2_SMART1, + ROCKCHIP_VOP2_CLUSTER2, + ROCKCHIP_VOP2_CLUSTER3, + ROCKCHIP_VOP2_ESMART2, + ROCKCHIP_VOP2_ESMART3, + ROCKCHIP_VOP2_PHY_ID_INVALID = -1, +}; + +extern const struct component_ops vop2_component_ops; + +#endif /* _ROCKCHIP_DRM_VOP2_H */ diff --git a/target/linux/rockchip/files-5.15/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/target/linux/rockchip/files-5.15/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c new file mode 100644 index 000000000..9bf0637bf --- /dev/null +++ b/target/linux/rockchip/files-5.15/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c @@ -0,0 +1,281 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) Rockchip Electronics Co.Ltd + * Author: Andy Yan + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rockchip_drm_vop2.h" + +static const uint32_t formats_win_full_10bit[] = { + DRM_FORMAT_XRGB8888, + DRM_FORMAT_ARGB8888, + DRM_FORMAT_XBGR8888, + DRM_FORMAT_ABGR8888, + DRM_FORMAT_RGB888, + DRM_FORMAT_BGR888, + DRM_FORMAT_RGB565, + DRM_FORMAT_BGR565, + DRM_FORMAT_NV12, + DRM_FORMAT_NV16, + DRM_FORMAT_NV24, +}; + +static const uint32_t formats_win_full_10bit_yuyv[] = { + DRM_FORMAT_XRGB8888, + DRM_FORMAT_ARGB8888, + DRM_FORMAT_XBGR8888, + DRM_FORMAT_ABGR8888, + DRM_FORMAT_RGB888, + DRM_FORMAT_BGR888, + DRM_FORMAT_RGB565, + DRM_FORMAT_BGR565, + DRM_FORMAT_NV12, + DRM_FORMAT_NV16, + DRM_FORMAT_NV24, + DRM_FORMAT_YVYU, + DRM_FORMAT_VYUY, +}; + +static const uint32_t formats_win_lite[] = { + DRM_FORMAT_XRGB8888, + DRM_FORMAT_ARGB8888, + DRM_FORMAT_XBGR8888, + DRM_FORMAT_ABGR8888, + DRM_FORMAT_RGB888, + DRM_FORMAT_BGR888, + DRM_FORMAT_RGB565, + DRM_FORMAT_BGR565, +}; + +static const uint64_t format_modifiers[] = { + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID, +}; + +static const uint64_t format_modifiers_afbc[] = { + DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16), + + DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | + AFBC_FORMAT_MOD_SPARSE), + + DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | + AFBC_FORMAT_MOD_YTR), + + DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | + AFBC_FORMAT_MOD_CBR), + + DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | + AFBC_FORMAT_MOD_YTR | + AFBC_FORMAT_MOD_SPARSE), + + DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | + AFBC_FORMAT_MOD_CBR | + AFBC_FORMAT_MOD_SPARSE), + + DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | + AFBC_FORMAT_MOD_YTR | + AFBC_FORMAT_MOD_CBR), + + DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | + AFBC_FORMAT_MOD_YTR | + AFBC_FORMAT_MOD_CBR | + AFBC_FORMAT_MOD_SPARSE), + + /* SPLIT mandates SPARSE, RGB modes mandates YTR */ + DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | + AFBC_FORMAT_MOD_YTR | + AFBC_FORMAT_MOD_SPARSE | + AFBC_FORMAT_MOD_SPLIT), + DRM_FORMAT_MOD_INVALID, +}; + +static const struct vop2_video_port_data rk3568_vop_video_ports[] = { + { + .id = 0, + .feature = VOP_FEATURE_OUTPUT_10BIT, + .gamma_lut_len = 1024, + .cubic_lut_len = 9 * 9 * 9, + .max_output = { 4096, 2304 }, + .pre_scan_max_dly = { 69, 53, 53, 42 }, + .offset = 0xc00, + }, { + .id = 1, + .gamma_lut_len = 1024, + .max_output = { 2048, 1536 }, + .pre_scan_max_dly = { 40, 40, 40, 40 }, + .offset = 0xd00, + }, { + .id = 2, + .gamma_lut_len = 1024, + .max_output = { 1920, 1080 }, + .pre_scan_max_dly = { 40, 40, 40, 40 }, + .offset = 0xe00, + }, +}; + +/* + * rk3568 vop with 2 cluster, 2 esmart win, 2 smart win. + * Every cluster can work as 4K win or split into two win. + * All win in cluster support AFBCD. + * + * Every esmart win and smart win support 4 Multi-region. + * + * Scale filter mode: + * + * * Cluster: bicubic for horizontal scale up, others use bilinear + * * ESmart: + * * nearest-neighbor/bilinear/bicubic for scale up + * * nearest-neighbor/bilinear/average for scale down + * + * + * @TODO describe the wind like cpu-map dt nodes; + */ +static const struct vop2_win_data rk3568_vop_win_data[] = { + { + .name = "Smart0-win0", + .phys_id = ROCKCHIP_VOP2_SMART0, + .base = 0x1c00, + .formats = formats_win_lite, + .nformats = ARRAY_SIZE(formats_win_lite), + .format_modifiers = format_modifiers, + .layer_sel_id = 3, + .supported_rotations = DRM_MODE_REFLECT_Y, + .type = DRM_PLANE_TYPE_PRIMARY, + .max_upscale_factor = 8, + .max_downscale_factor = 8, + .dly = { 20, 47, 41 }, + }, { + .name = "Smart1-win0", + .phys_id = ROCKCHIP_VOP2_SMART1, + .formats = formats_win_lite, + .nformats = ARRAY_SIZE(formats_win_lite), + .format_modifiers = format_modifiers, + .base = 0x1e00, + .layer_sel_id = 7, + .supported_rotations = DRM_MODE_REFLECT_Y, + .type = DRM_PLANE_TYPE_PRIMARY, + .max_upscale_factor = 8, + .max_downscale_factor = 8, + .dly = { 20, 47, 41 }, + }, { + .name = "Esmart1-win0", + .phys_id = ROCKCHIP_VOP2_ESMART1, + .formats = formats_win_full_10bit_yuyv, + .nformats = ARRAY_SIZE(formats_win_full_10bit_yuyv), + .format_modifiers = format_modifiers, + .base = 0x1a00, + .layer_sel_id = 6, + .supported_rotations = DRM_MODE_REFLECT_Y, + .type = DRM_PLANE_TYPE_PRIMARY, + .max_upscale_factor = 8, + .max_downscale_factor = 8, + .dly = { 20, 47, 41 }, + }, { + .name = "Esmart0-win0", + .phys_id = ROCKCHIP_VOP2_ESMART0, + .formats = formats_win_full_10bit_yuyv, + .nformats = ARRAY_SIZE(formats_win_full_10bit_yuyv), + .format_modifiers = format_modifiers, + .base = 0x1800, + .layer_sel_id = 2, + .supported_rotations = DRM_MODE_REFLECT_Y, + .type = DRM_PLANE_TYPE_OVERLAY, + .max_upscale_factor = 8, + .max_downscale_factor = 8, + .dly = { 20, 47, 41 }, + }, { + .name = "Cluster0-win0", + .phys_id = ROCKCHIP_VOP2_CLUSTER0, + .base = 0x1000, + .formats = formats_win_full_10bit, + .nformats = ARRAY_SIZE(formats_win_full_10bit), + .format_modifiers = format_modifiers_afbc, + .layer_sel_id = 0, + .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 | + DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y, + .max_upscale_factor = 4, + .max_downscale_factor = 4, + .dly = { 0, 27, 21 }, + .type = DRM_PLANE_TYPE_OVERLAY, + .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER, + }, { + .name = "Cluster1-win0", + .phys_id = ROCKCHIP_VOP2_CLUSTER1, + .base = 0x1200, + .formats = formats_win_full_10bit, + .nformats = ARRAY_SIZE(formats_win_full_10bit), + .format_modifiers = format_modifiers_afbc, + .layer_sel_id = 1, + .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 | + DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y, + .type = DRM_PLANE_TYPE_OVERLAY, + .max_upscale_factor = 4, + .max_downscale_factor = 4, + .dly = { 0, 27, 21 }, + .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER, + }, +}; + +static const struct vop2_data rk3566_vop = { + .nr_vps = 3, + .max_input = { 4096, 2304 }, + .max_output = { 4096, 2304 }, + .vp = rk3568_vop_video_ports, + .win = rk3568_vop_win_data, + .win_size = ARRAY_SIZE(rk3568_vop_win_data), + .soc_id = 3566, +}; + +static const struct vop2_data rk3568_vop = { + .nr_vps = 3, + .max_input = { 4096, 2304 }, + .max_output = { 4096, 2304 }, + .vp = rk3568_vop_video_ports, + .win = rk3568_vop_win_data, + .win_size = ARRAY_SIZE(rk3568_vop_win_data), + .soc_id = 3568, +}; + +static const struct of_device_id vop2_dt_match[] = { + { + .compatible = "rockchip,rk3566-vop", + .data = &rk3566_vop, + }, { + .compatible = "rockchip,rk3568-vop", + .data = &rk3568_vop, + }, { + }, +}; +MODULE_DEVICE_TABLE(of, vop2_dt_match); + +static int vop2_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + + return component_add(dev, &vop2_component_ops); +} + +static int vop2_remove(struct platform_device *pdev) +{ + component_del(&pdev->dev, &vop2_component_ops); + + return 0; +} + +struct platform_driver vop2_platform_driver = { + .probe = vop2_probe, + .remove = vop2_remove, + .driver = { + .name = "rockchip-vop2", + .of_match_table = of_match_ptr(vop2_dt_match), + }, +}; diff --git a/target/linux/rockchip/files-5.15/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/target/linux/rockchip/files-5.15/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c new file mode 100644 index 000000000..7b213825f --- /dev/null +++ b/target/linux/rockchip/files-5.15/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c @@ -0,0 +1,581 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Rockchip PIPE USB3.0 PCIE SATA Combo Phy driver + * + * Copyright (C) 2021 Rockchip Electronics Co., Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define BIT_WRITEABLE_SHIFT 16 +#define REF_CLOCK_24MHz (24 * HZ_PER_MHZ) +#define REF_CLOCK_25MHz (25 * HZ_PER_MHZ) +#define REF_CLOCK_100MHz (100 * HZ_PER_MHZ) + +/* COMBO PHY REG */ +#define PHYREG6 0x14 +#define PHYREG6_PLL_DIV_MASK GENMASK(7, 6) +#define PHYREG6_PLL_DIV_SHIFT 6 +#define PHYREG6_PLL_DIV_2 1 + +#define PHYREG7 0x18 +#define PHYREG7_TX_RTERM_MASK GENMASK(7, 4) +#define PHYREG7_TX_RTERM_SHIFT 4 +#define PHYREG7_TX_RTERM_50OHM 8 +#define PHYREG7_RX_RTERM_MASK GENMASK(3, 0) +#define PHYREG7_RX_RTERM_SHIFT 0 +#define PHYREG7_RX_RTERM_44OHM 15 + +#define PHYREG8 0x1C +#define PHYREG8_SSC_EN BIT(4) + +#define PHYREG11 0x28 +#define PHYREG11_SU_TRIM_0_7 0xF0 + +#define PHYREG12 0x2C +#define PHYREG12_PLL_LPF_ADJ_VALUE 4 + +#define PHYREG13 0x30 +#define PHYREG13_RESISTER_MASK GENMASK(5, 4) +#define PHYREG13_RESISTER_SHIFT 0x4 +#define PHYREG13_RESISTER_HIGH_Z 3 +#define PHYREG13_CKRCV_AMP0 BIT(7) + +#define PHYREG14 0x34 +#define PHYREG14_CKRCV_AMP1 BIT(0) + +#define PHYREG15 0x38 +#define PHYREG15_CTLE_EN BIT(0) +#define PHYREG15_SSC_CNT_MASK GENMASK(7, 6) +#define PHYREG15_SSC_CNT_SHIFT 6 +#define PHYREG15_SSC_CNT_VALUE 1 + +#define PHYREG16 0x3C +#define PHYREG16_SSC_CNT_VALUE 0x5f + +#define PHYREG18 0x44 +#define PHYREG18_PLL_LOOP 0x32 + +#define PHYREG32 0x7C +#define PHYREG32_SSC_MASK GENMASK(7, 4) +#define PHYREG32_SSC_DIR_SHIFT 4 +#define PHYREG32_SSC_UPWARD 0 +#define PHYREG32_SSC_DOWNWARD 1 +#define PHYREG32_SSC_OFFSET_SHIFT 6 +#define PHYREG32_SSC_OFFSET_500PPM 1 + +#define PHYREG33 0x80 +#define PHYREG33_PLL_KVCO_MASK GENMASK(4, 2) +#define PHYREG33_PLL_KVCO_SHIFT 2 +#define PHYREG33_PLL_KVCO_VALUE 2 + +struct rockchip_combphy_priv; + +struct combphy_reg { + u16 offset; + u16 bitend; + u16 bitstart; + u16 disable; + u16 enable; +}; + +struct rockchip_combphy_grfcfg { + struct combphy_reg pcie_mode_set; + struct combphy_reg usb_mode_set; + struct combphy_reg sgmii_mode_set; + struct combphy_reg qsgmii_mode_set; + struct combphy_reg pipe_rxterm_set; + struct combphy_reg pipe_txelec_set; + struct combphy_reg pipe_txcomp_set; + struct combphy_reg pipe_clk_25m; + struct combphy_reg pipe_clk_100m; + struct combphy_reg pipe_phymode_sel; + struct combphy_reg pipe_rate_sel; + struct combphy_reg pipe_rxterm_sel; + struct combphy_reg pipe_txelec_sel; + struct combphy_reg pipe_txcomp_sel; + struct combphy_reg pipe_clk_ext; + struct combphy_reg pipe_sel_usb; + struct combphy_reg pipe_sel_qsgmii; + struct combphy_reg pipe_phy_status; + struct combphy_reg con0_for_pcie; + struct combphy_reg con1_for_pcie; + struct combphy_reg con2_for_pcie; + struct combphy_reg con3_for_pcie; + struct combphy_reg con0_for_sata; + struct combphy_reg con1_for_sata; + struct combphy_reg con2_for_sata; + struct combphy_reg con3_for_sata; + struct combphy_reg pipe_con0_for_sata; + struct combphy_reg pipe_xpcs_phy_ready; +}; + +struct rockchip_combphy_cfg { + const struct rockchip_combphy_grfcfg *grfcfg; + int (*combphy_cfg)(struct rockchip_combphy_priv *priv); +}; + +struct rockchip_combphy_priv { + u8 type; + void __iomem *mmio; + int num_clks; + struct clk_bulk_data *clks; + struct device *dev; + struct regmap *pipe_grf; + struct regmap *phy_grf; + struct phy *phy; + struct reset_control *phy_rst; + const struct rockchip_combphy_cfg *cfg; + bool enable_ssc; + bool ext_refclk; + struct clk *refclk; +}; + +static void rockchip_combphy_updatel(struct rockchip_combphy_priv *priv, + int mask, int val, int reg) +{ + unsigned int temp; + + temp = readl(priv->mmio + reg); + temp = (temp & ~(mask)) | val; + writel(temp, priv->mmio + reg); +} + +static int rockchip_combphy_param_write(struct regmap *base, + const struct combphy_reg *reg, bool en) +{ + u32 val, mask, tmp; + + tmp = en ? reg->enable : reg->disable; + mask = GENMASK(reg->bitend, reg->bitstart); + val = (tmp << reg->bitstart) | (mask << BIT_WRITEABLE_SHIFT); + + return regmap_write(base, reg->offset, val); +} + +static u32 rockchip_combphy_is_ready(struct rockchip_combphy_priv *priv) +{ + const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg; + u32 mask, val; + + mask = GENMASK(cfg->pipe_phy_status.bitend, + cfg->pipe_phy_status.bitstart); + + regmap_read(priv->phy_grf, cfg->pipe_phy_status.offset, &val); + val = (val & mask) >> cfg->pipe_phy_status.bitstart; + + return val; +} + +static int rockchip_combphy_init(struct phy *phy) +{ + struct rockchip_combphy_priv *priv = phy_get_drvdata(phy); + const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg; + u32 val; + int ret; + + ret = clk_bulk_prepare_enable(priv->num_clks, priv->clks); + if (ret) { + dev_err(priv->dev, "failed to enable clks\n"); + return ret; + } + + switch (priv->type) { + case PHY_TYPE_PCIE: + case PHY_TYPE_USB3: + case PHY_TYPE_SATA: + case PHY_TYPE_SGMII: + case PHY_TYPE_QSGMII: + if (priv->cfg->combphy_cfg) + ret = priv->cfg->combphy_cfg(priv); + break; + default: + dev_err(priv->dev, "incompatible PHY type\n"); + ret = -EINVAL; + break; + } + + if (ret) { + dev_err(priv->dev, "failed to init phy for phy type %x\n", priv->type); + goto err_clk; + } + + ret = reset_control_deassert(priv->phy_rst); + if (ret) + goto err_clk; + + if (priv->type == PHY_TYPE_USB3) { + ret = readx_poll_timeout_atomic(rockchip_combphy_is_ready, + priv, val, + val == cfg->pipe_phy_status.enable, + 10, 1000); + if (ret) + dev_warn(priv->dev, "wait phy status ready timeout\n"); + } + + return 0; + +err_clk: + clk_bulk_disable_unprepare(priv->num_clks, priv->clks); + + return ret; +} + +static int rockchip_combphy_exit(struct phy *phy) +{ + struct rockchip_combphy_priv *priv = phy_get_drvdata(phy); + + clk_bulk_disable_unprepare(priv->num_clks, priv->clks); + reset_control_assert(priv->phy_rst); + + return 0; +} + +static const struct phy_ops rochchip_combphy_ops = { + .init = rockchip_combphy_init, + .exit = rockchip_combphy_exit, + .owner = THIS_MODULE, +}; + +static struct phy *rockchip_combphy_xlate(struct device *dev, struct of_phandle_args *args) +{ + struct rockchip_combphy_priv *priv = dev_get_drvdata(dev); + + if (args->args_count != 1) { + dev_err(dev, "invalid number of arguments\n"); + return ERR_PTR(-EINVAL); + } + + if (priv->type != PHY_NONE && priv->type != args->args[0]) + dev_warn(dev, "phy type select %d overwriting type %d\n", + args->args[0], priv->type); + + priv->type = args->args[0]; + + return priv->phy; +} + +static int rockchip_combphy_parse_dt(struct device *dev, struct rockchip_combphy_priv *priv) +{ + int i; + + priv->num_clks = devm_clk_bulk_get_all(dev, &priv->clks); + if (priv->num_clks < 1) + return -EINVAL; + + priv->refclk = NULL; + for (i = 0; i < priv->num_clks; i++) { + if (!strncmp(priv->clks[i].id, "ref", 3)) { + priv->refclk = priv->clks[i].clk; + break; + } + } + + if (!priv->refclk) { + dev_err(dev, "no refclk found\n"); + return -EINVAL; + } + + priv->pipe_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,pipe-grf"); + if (IS_ERR(priv->pipe_grf)) { + dev_err(dev, "failed to find peri_ctrl pipe-grf regmap\n"); + return PTR_ERR(priv->pipe_grf); + } + + priv->phy_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,pipe-phy-grf"); + if (IS_ERR(priv->phy_grf)) { + dev_err(dev, "failed to find peri_ctrl pipe-phy-grf regmap\n"); + return PTR_ERR(priv->phy_grf); + } + + priv->enable_ssc = device_property_present(dev, "rockchip,enable-ssc"); + + priv->ext_refclk = device_property_present(dev, "rockchip,ext-refclk"); + + priv->phy_rst = devm_reset_control_array_get_exclusive(dev); + if (IS_ERR(priv->phy_rst)) + return dev_err_probe(dev, PTR_ERR(priv->phy_rst), "failed to get phy reset\n"); + + return 0; +} + +static int rockchip_combphy_probe(struct platform_device *pdev) +{ + struct phy_provider *phy_provider; + struct device *dev = &pdev->dev; + struct rockchip_combphy_priv *priv; + const struct rockchip_combphy_cfg *phy_cfg; + struct resource *res; + int ret; + + phy_cfg = of_device_get_match_data(dev); + if (!phy_cfg) { + dev_err(dev, "no OF match data provided\n"); + return -EINVAL; + } + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->mmio = devm_platform_get_and_ioremap_resource(pdev, 0, &res); + if (IS_ERR(priv->mmio)) { + ret = PTR_ERR(priv->mmio); + return ret; + } + + priv->dev = dev; + priv->type = PHY_NONE; + priv->cfg = phy_cfg; + + ret = rockchip_combphy_parse_dt(dev, priv); + if (ret) + return ret; + + ret = reset_control_assert(priv->phy_rst); + if (ret) { + dev_err(dev, "failed to reset phy\n"); + return ret; + } + + priv->phy = devm_phy_create(dev, NULL, &rochchip_combphy_ops); + if (IS_ERR(priv->phy)) { + dev_err(dev, "failed to create combphy\n"); + return PTR_ERR(priv->phy); + } + + dev_set_drvdata(dev, priv); + phy_set_drvdata(priv->phy, priv); + + phy_provider = devm_of_phy_provider_register(dev, rockchip_combphy_xlate); + + return PTR_ERR_OR_ZERO(phy_provider); +} + +static int rk3568_combphy_cfg(struct rockchip_combphy_priv *priv) +{ + const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg; + unsigned long rate; + u32 val; + + switch (priv->type) { + case PHY_TYPE_PCIE: + /* Set SSC downward spread spectrum. */ + rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, + PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT, + PHYREG32); + + rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true); + rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true); + rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_pcie, true); + rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_pcie, true); + break; + + case PHY_TYPE_USB3: + /* Set SSC downward spread spectrum. */ + rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, + PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT, + PHYREG32); + + /* Enable adaptive CTLE for USB3.0 Rx. */ + val = readl(priv->mmio + PHYREG15); + val |= PHYREG15_CTLE_EN; + writel(val, priv->mmio + PHYREG15); + + /* Set PLL KVCO fine tuning signals. */ + rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, + PHYREG33_PLL_KVCO_VALUE << PHYREG33_PLL_KVCO_SHIFT, + PHYREG33); + + /* Enable controlling random jitter. */ + writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12); + + /* Set PLL input clock divider 1/2. */ + rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK, + PHYREG6_PLL_DIV_2 << PHYREG6_PLL_DIV_SHIFT, + PHYREG6); + + writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18); + writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11); + + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_sel_usb, true); + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false); + rockchip_combphy_param_write(priv->phy_grf, &cfg->usb_mode_set, true); + break; + + case PHY_TYPE_SATA: + /* Enable adaptive CTLE for SATA Rx. */ + val = readl(priv->mmio + PHYREG15); + val |= PHYREG15_CTLE_EN; + writel(val, priv->mmio + PHYREG15); + /* + * Set tx_rterm=50ohm and rx_rterm=44ohm for SATA. + * 0: 60ohm, 8: 50ohm 15: 44ohm (by step abort 1ohm) + */ + val = PHYREG7_TX_RTERM_50OHM << PHYREG7_TX_RTERM_SHIFT; + val |= PHYREG7_RX_RTERM_44OHM << PHYREG7_RX_RTERM_SHIFT; + writel(val, priv->mmio + PHYREG7); + + rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_sata, true); + rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_sata, true); + rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_sata, true); + rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_sata, true); + rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true); + break; + + case PHY_TYPE_SGMII: + rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_xpcs_phy_ready, true); + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_phymode_sel, true); + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_sel_qsgmii, true); + rockchip_combphy_param_write(priv->phy_grf, &cfg->sgmii_mode_set, true); + break; + + case PHY_TYPE_QSGMII: + rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_xpcs_phy_ready, true); + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_phymode_sel, true); + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_rate_sel, true); + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_sel_qsgmii, true); + rockchip_combphy_param_write(priv->phy_grf, &cfg->qsgmii_mode_set, true); + break; + + default: + dev_err(priv->dev, "incompatible PHY type\n"); + return -EINVAL; + } + + rate = clk_get_rate(priv->refclk); + + switch (rate) { + case REF_CLOCK_24MHz: + if (priv->type == PHY_TYPE_USB3 || priv->type == PHY_TYPE_SATA) { + /* Set ssc_cnt[9:0]=0101111101 & 31.5KHz. */ + val = PHYREG15_SSC_CNT_VALUE << PHYREG15_SSC_CNT_SHIFT; + rockchip_combphy_updatel(priv, PHYREG15_SSC_CNT_MASK, + val, PHYREG15); + + writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16); + } + break; + + case REF_CLOCK_25MHz: + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_25m, true); + break; + + case REF_CLOCK_100MHz: + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); + if (priv->type == PHY_TYPE_PCIE) { + /* PLL KVCO fine tuning. */ + val = PHYREG33_PLL_KVCO_VALUE << PHYREG33_PLL_KVCO_SHIFT; + rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, + val, PHYREG33); + + /* Enable controlling random jitter. */ + writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12); + + val = PHYREG6_PLL_DIV_2 << PHYREG6_PLL_DIV_SHIFT; + rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK, + val, PHYREG6); + + writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18); + writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11); + } else if (priv->type == PHY_TYPE_SATA) { + /* downward spread spectrum +500ppm */ + val = PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT; + val |= PHYREG32_SSC_OFFSET_500PPM << PHYREG32_SSC_OFFSET_SHIFT; + rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32); + } + break; + + default: + dev_err(priv->dev, "unsupported rate: %lu\n", rate); + return -EINVAL; + } + + if (priv->ext_refclk) { + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true); + if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) { + val = PHYREG13_RESISTER_HIGH_Z << PHYREG13_RESISTER_SHIFT; + val |= PHYREG13_CKRCV_AMP0; + rockchip_combphy_updatel(priv, PHYREG13_RESISTER_MASK, val, PHYREG13); + + val = readl(priv->mmio + PHYREG14); + val |= PHYREG14_CKRCV_AMP1; + writel(val, priv->mmio + PHYREG14); + } + } + + if (priv->enable_ssc) { + val = readl(priv->mmio + PHYREG8); + val |= PHYREG8_SSC_EN; + writel(val, priv->mmio + PHYREG8); + } + + return 0; +} + +static const struct rockchip_combphy_grfcfg rk3568_combphy_grfcfgs = { + /* pipe-phy-grf */ + .pcie_mode_set = { 0x0000, 5, 0, 0x00, 0x11 }, + .usb_mode_set = { 0x0000, 5, 0, 0x00, 0x04 }, + .sgmii_mode_set = { 0x0000, 5, 0, 0x00, 0x01 }, + .qsgmii_mode_set = { 0x0000, 5, 0, 0x00, 0x21 }, + .pipe_rxterm_set = { 0x0000, 12, 12, 0x00, 0x01 }, + .pipe_txelec_set = { 0x0004, 1, 1, 0x00, 0x01 }, + .pipe_txcomp_set = { 0x0004, 4, 4, 0x00, 0x01 }, + .pipe_clk_25m = { 0x0004, 14, 13, 0x00, 0x01 }, + .pipe_clk_100m = { 0x0004, 14, 13, 0x00, 0x02 }, + .pipe_phymode_sel = { 0x0008, 1, 1, 0x00, 0x01 }, + .pipe_rate_sel = { 0x0008, 2, 2, 0x00, 0x01 }, + .pipe_rxterm_sel = { 0x0008, 8, 8, 0x00, 0x01 }, + .pipe_txelec_sel = { 0x0008, 12, 12, 0x00, 0x01 }, + .pipe_txcomp_sel = { 0x0008, 15, 15, 0x00, 0x01 }, + .pipe_clk_ext = { 0x000c, 9, 8, 0x02, 0x01 }, + .pipe_sel_usb = { 0x000c, 14, 13, 0x00, 0x01 }, + .pipe_sel_qsgmii = { 0x000c, 15, 13, 0x00, 0x07 }, + .pipe_phy_status = { 0x0034, 6, 6, 0x01, 0x00 }, + .con0_for_pcie = { 0x0000, 15, 0, 0x00, 0x1000 }, + .con1_for_pcie = { 0x0004, 15, 0, 0x00, 0x0000 }, + .con2_for_pcie = { 0x0008, 15, 0, 0x00, 0x0101 }, + .con3_for_pcie = { 0x000c, 15, 0, 0x00, 0x0200 }, + .con0_for_sata = { 0x0000, 15, 0, 0x00, 0x0119 }, + .con1_for_sata = { 0x0004, 15, 0, 0x00, 0x0040 }, + .con2_for_sata = { 0x0008, 15, 0, 0x00, 0x80c3 }, + .con3_for_sata = { 0x000c, 15, 0, 0x00, 0x4407 }, + /* pipe-grf */ + .pipe_con0_for_sata = { 0x0000, 15, 0, 0x00, 0x2220 }, + .pipe_xpcs_phy_ready = { 0x0040, 2, 2, 0x00, 0x01 }, +}; + +static const struct rockchip_combphy_cfg rk3568_combphy_cfgs = { + .grfcfg = &rk3568_combphy_grfcfgs, + .combphy_cfg = rk3568_combphy_cfg, +}; + +static const struct of_device_id rockchip_combphy_of_match[] = { + { + .compatible = "rockchip,rk3568-naneng-combphy", + .data = &rk3568_combphy_cfgs, + }, + { }, +}; +MODULE_DEVICE_TABLE(of, rockchip_combphy_of_match); + +static struct platform_driver rockchip_combphy_driver = { + .probe = rockchip_combphy_probe, + .driver = { + .name = "rockchip-naneng-combphy", + .of_match_table = rockchip_combphy_of_match, + }, +}; +module_platform_driver(rockchip_combphy_driver); + +MODULE_DESCRIPTION("Rockchip NANENG COMBPHY driver"); +MODULE_LICENSE("GPL v2"); diff --git a/target/linux/rockchip/files-5.15/include/dt-bindings/soc/rockchip,vop2.h b/target/linux/rockchip/files-5.15/include/dt-bindings/soc/rockchip,vop2.h new file mode 100644 index 000000000..6e66a802b --- /dev/null +++ b/target/linux/rockchip/files-5.15/include/dt-bindings/soc/rockchip,vop2.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ + +#ifndef __DT_BINDINGS_ROCKCHIP_VOP2_H +#define __DT_BINDINGS_ROCKCHIP_VOP2_H + +#define ROCKCHIP_VOP2_EP_RGB0 1 +#define ROCKCHIP_VOP2_EP_HDMI0 2 +#define ROCKCHIP_VOP2_EP_EDP0 3 +#define ROCKCHIP_VOP2_EP_MIPI0 4 +#define ROCKCHIP_VOP2_EP_LVDS0 5 +#define ROCKCHIP_VOP2_EP_MIPI1 6 +#define ROCKCHIP_VOP2_EP_LVDS1 7 + +#endif /* __DT_BINDINGS_ROCKCHIP_VOP2_H */ diff --git a/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2c.dts b/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2c.dts new file mode 100644 index 000000000..530739a69 --- /dev/null +++ b/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2c.dts @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2021 FriendlyElec Computer Tech. Co., Ltd. + * (http://www.friendlyarm.com) + * + * Copyright (c) 2021 Tianling Shen + */ + +#include "rk3328-nanopi-r2s.dts" + +/ { + model = "FriendlyElec NanoPi R2C"; + compatible = "friendlyarm,nanopi-r2c", "rockchip,rk3328"; +}; + +&gmac2io { + phy-handle = <&yt8521s>; + + mdio { + /delete-node/ ethernet-phy@1; + + yt8521s: ethernet-phy@3 { + compatible = "ethernet-phy-id0000.011a", + "ethernet-phy-ieee802.3-c22"; + reg = <3>; + pinctrl-0 = <ð_phy_reset_pin>; + pinctrl-names = "default"; + reset-assert-us = <10000>; + reset-deassert-us = <50000>; + reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&lan_led { + label = "nanopi-r2c:green:lan"; +}; + +&rtl8153 { + realtek,led-data = <0x78>; +}; + +&sys_led { + label = "nanopi-r2c:red:sys"; +}; + +&wan_led { + label = "nanopi-r2c:green:wan"; +}; diff --git a/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus-lts.dts b/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus-lts.dts new file mode 100644 index 000000000..a690c062f --- /dev/null +++ b/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus-lts.dts @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2016 Xunlong Software. Co., Ltd. + * (http://www.orangepi.org) + * + * Copyright (c) 2021 Tianling Shen + */ + +#include "rk3328-orangepi-r1-plus.dts" + +/ { + model = "Xunlong Orange Pi R1 Plus LTS"; + compatible = "xunlong,orangepi-r1-plus-lts", "rockchip,rk3328"; +}; + +&dmc_opp_table { + opp-798000000 { + status = "disabled"; + }; + opp-840000000 { + status = "disabled"; + }; + opp-924000000 { + status = "disabled"; + }; + opp-1056000000 { + status = "disabled"; + }; +}; + +&gmac2io { + phy-handle = <&yt8531c>; + tx_delay = <0x19>; + rx_delay = <0x05>; + + mdio { + /delete-node/ ethernet-phy@1; + + yt8531c: ethernet-phy@0 { + compatible = "ethernet-phy-id4f51.e91b", + "ethernet-phy-ieee802.3-c22"; + reg = <0>; + pinctrl-0 = <ð_phy_reset_pin>; + pinctrl-names = "default"; + reset-assert-us = <15000>; + reset-deassert-us = <50000>; + reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&lan_led { + label = "orangepi-r1-plus-lts:green:lan"; +}; + +&rtl8153 { + realtek,led-data = <0x78>; +}; + +&sys_led { + label = "orangepi-r1-plus-lts:red:sys"; +}; + +&wan_led { + label = "orangepi-r1-plus-lts:green:wan"; +}; diff --git a/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dts b/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dts new file mode 100644 index 000000000..ed585daf4 --- /dev/null +++ b/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dts @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +#include "rk3328-nanopi-r2s.dts" + +/ { + model = "Xunlong Orange Pi R1 Plus"; + compatible = "xunlong,orangepi-r1-plus", "rockchip,rk3328"; +}; + +&lan_led { + label = "orangepi-r1-plus:green:lan"; +}; + +&spi0 { + max-freq = <48000000>; + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <10000000>; + }; +}; + +&sys_led { + gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>; + label = "orangepi-r1-plus:red:sys"; +}; + +&sys_led_pin { + rockchip,pins = <3 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>; +}; + +&uart1 { + status = "okay"; +}; + +&wan_led { + label = "orangepi-r1-plus:green:wan"; +}; diff --git a/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dts b/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dts index 27ed85acc..3cda9452d 100644 --- a/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dts +++ b/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dts @@ -1,8 +1,825 @@ // SPDX-License-Identifier: (GPL-2.0+ OR MIT) + /dts-v1/; +#include +#include +#include +#include +#include "rk3568.dtsi" / { - model = "FriendlyARM NanoPi R5S"; - compatible = "friendlyarm,nanopi-r5s", "rockchip,rk3568"; + model = "FriendlyElec NanoPi R5S"; + compatible = "friendlyelec,nanopi-r5s", "rockchip,rk3568"; + + aliases { + ethernet0 = &gmac0; + mmc0 = &sdmmc0; + mmc1 = &sdhci; + led-boot = &sys_led; + led-failsafe = &sys_led; + led-running = &sys_led; + led-upgrade = &sys_led; + }; + + chosen: chosen { + stdout-path = "serial2:1500000n8"; + }; + + fan: pwm-fan { + compatible = "pwm-fan"; + cooling-levels = <0 18 102 170 255>; + #cooling-cells = <2>; + fan-supply = <&vcc5v0_sysp>; + pwms = <&pwm0 0 50000 0>; + }; + + firmware { + optee: optee { + compatible = "linaro,optee-tz"; + method = "smc"; + }; + }; + + cspmu: cspmu@fd90c000 { + compatible = "rockchip,cspmu"; + reg = <0x0 0xfd90c000 0x0 0x1000>, + <0x0 0xfd90d000 0x0 0x1000>, + <0x0 0xfd90e000 0x0 0x1000>, + <0x0 0xfd90f000 0x0 0x1000>; + }; + + gpio-key { + compatible = "gpio-key"; + pinctrl-names = "default"; + pinctrl-0 = <&key1_pin>; + + button@1 { + debounce-interval = <50>; + gpios = <&gpio4 RK_PA0 GPIO_ACTIVE_LOW>; + wakeup-source; + }; + }; + + gpio-leds { + compatible = "gpio-leds"; + + sys_led: led-sys { + gpios = <&gpio4 RK_PD2 GPIO_ACTIVE_HIGH>; + label = "red:power"; + linux,default-trigger = "heartbeat"; + pinctrl-names = "default"; + pinctrl-0 = <&sys_led_pin>; + }; + + wan_led: led-wan { + gpios = <&gpio2 RK_PC1 GPIO_ACTIVE_HIGH>; + label = "green:wan"; + pinctrl-names = "default"; + pinctrl-0 = <&wan_led_pin>; + }; + + lan1_led: led-lan1 { + gpios = <&gpio3 RK_PD6 GPIO_ACTIVE_HIGH>; + label = "green:lan1"; + pinctrl-names = "default"; + pinctrl-0 = <&lan1_led_pin>; + }; + + lan2_led: led-lan2 { + gpios = <&gpio3 RK_PD7 GPIO_ACTIVE_HIGH>; + label = "green:lan2"; + pinctrl-names = "default"; + pinctrl-0 = <&lan2_led_pin>; + }; + }; + + hdmi-con { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_con_in: endpoint { + remote-endpoint = <&hdmi_out_con>; + }; + }; + }; + + vdd_usbc: vdd-usbc { + compatible = "regulator-fixed"; + regulator-name = "vdd_usbc"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + vcc3v3_sys: vcc3v3-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vdd_usbc>; + }; + + vcc5v0_sys: vcc5v0-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vdd_usbc>; + }; + + pcie30_avdd0v9: pcie30-avdd0v9 { + compatible = "regulator-fixed"; + regulator-name = "pcie30_avdd0v9"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + vin-supply = <&vcc3v3_sys>; + }; + + pcie30_avdd1v8: pcie30-avdd1v8 { + compatible = "regulator-fixed"; + regulator-name = "pcie30_avdd1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc3v3_sys>; + }; + + vcc3v3_pcie: vcc3v3-pcie-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_pcie"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + enable-active-high; + gpios = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>; + startup-delay-us = <200000>; + vin-supply = <&vcc5v0_sys>; + }; + + vcc3v3_pcie: vcc3v3-pcie-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_pcie"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + enable-active-high; + gpio = <&gpio0 RK_PC6 GPIO_ACTIVE_HIGH>; + startup-delay-us = <50000>; + vin-supply = <&vcc3v3_pcie>; + }; + + vcc3v3_ngff: vcc3v3-ngff-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_ngff"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + enable-active-high; + gpio = <&gpio4 RK_PC1 GPIO_ACTIVE_HIGH>; + startup-delay-us = <50000>; + vin-supply = <&vcc3v3_pcie>; + }; + + vcc5v0_usb: vcc5v0_usb { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_usb"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vdd_usbc>; + }; + + vcc5v0_usb_host: vcc5v0-usb-host { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc5v0_usb_host_en>; + regulator-name = "vcc5v0_usb_host"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc5v0_usb>; + }; + + vcc5v0_sysp: vcc5v0-sysp { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_sysp"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc3v3_sys>; + }; + + vcc5v0_usb_otg: vcc5v0-usb-otg { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc5v0_usb_otg_en>; + regulator-name = "vcc5v0_usb_otg"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc5v0_usb>; + }; }; + +&combphy0 { + status = "okay"; +}; + +&combphy1 { + status = "okay"; +}; + +&combphy2 { + status = "okay"; +}; + +&cpu0 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu1 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu2 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu3 { + cpu-supply = <&vdd_cpu>; +}; + +&gmac0 { + phy-mode = "rgmii"; + clock_in_out = "output"; + + snps,reset-gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_LOW>; + snps,reset-active-low; + /* Reset time is 20ms, 100ms for rtl8211f */ + snps,reset-delays-us = <0 20000 100000>; + + assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>; + assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>, <&cru CLK_MAC0_2TOP>; + + pinctrl-names = "default"; + pinctrl-0 = <&gmac0_miim + &gmac0_tx_bus2 + &gmac0_rx_bus2 + &gmac0_rgmii_clk + &gmac0_rgmii_bus>; + + tx_delay = <0x3c>; + rx_delay = <0x2f>; + + phy-handle = <&rgmii_phy0>; + status = "okay"; +}; + + +&gpu { + mali-supply = <&vdd_gpu>; + status = "okay"; +}; + +&hdmi { + avdd-0v9-supply = <&vdda0v9_image>; + avdd-1v8-supply = <&vcca1v8_image>; + status = "okay"; +}; + +&hdmi_in { + hdmi_in_vp0: endpoint { + remote-endpoint = <&vp0_out_hdmi>; + }; +}; + +&hdmi_out { + hdmi_out_con: endpoint { + remote-endpoint = <&hdmi_con_in>; + }; +}; + +&hdmi_sound { + status = "okay"; +}; + +&i2c0 { + status = "okay"; + + vdd_cpu: regulator@1c { + compatible = "tcs,tcs4525"; + reg = <0x1c>; + fcs,suspend-voltage-selector = <1>; + regulator-name = "vdd_cpu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1150000>; + regulator-ramp-delay = <2300>; + vin-supply = <&vcc5v0_sys>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + rk809: pmic@20 { + compatible = "rockchip,rk809"; + reg = <0x20>; + interrupt-parent = <&gpio0>; + interrupts = ; + #clock-cells = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int>; + rockchip,system-power-controller; + vcc1-supply = <&vcc3v3_sys>; + vcc2-supply = <&vcc3v3_sys>; + vcc3-supply = <&vcc3v3_sys>; + vcc4-supply = <&vcc3v3_sys>; + vcc5-supply = <&vcc3v3_sys>; + vcc6-supply = <&vcc3v3_sys>; + vcc7-supply = <&vcc3v3_sys>; + vcc8-supply = <&vcc3v3_sys>; + vcc9-supply = <&vcc3v3_sys>; + wakeup-source; + + regulators { + vdd_logic: DCDC_REG1 { + regulator-name = "vdd_logic"; + regulator-always-on; + regulator-boot-on; + regulator-init-microvolt = <900000>; + regulator-initial-mode = <0x2>; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_gpu: DCDC_REG2 { + regulator-name = "vdd_gpu"; + regulator-always-on; + regulator-init-microvolt = <900000>; + regulator-initial-mode = <0x2>; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <0x2>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vdd_npu: DCDC_REG4 { + regulator-name = "vdd_npu"; + regulator-init-microvolt = <900000>; + regulator-initial-mode = <0x2>; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_1v8: DCDC_REG5 { + regulator-name = "vcc_1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda0v9_image: LDO_REG1 { + regulator-name = "vdda0v9_image"; + regulator-always-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda_0v9: LDO_REG2 { + regulator-name = "vdda_0v9"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda0v9_pmu: LDO_REG3 { + regulator-name = "vdda0v9_pmu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <900000>; + }; + }; + + vccio_acodec: LDO_REG4 { + regulator-name = "vccio_acodec"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vccio_sd: LDO_REG5 { + regulator-name = "vccio_sd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc3v3_pmu: LDO_REG6 { + regulator-name = "vcc3v3_pmu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcca_1v8: LDO_REG7 { + regulator-name = "vcca_1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcca1v8_pmu: LDO_REG8 { + regulator-name = "vcca1v8_pmu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcca1v8_image: LDO_REG9 { + regulator-name = "vcca1v8_image"; + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_3v3: SWITCH_REG1 { + regulator-name = "vcc_3v3"; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc3v3_sd: SWITCH_REG2 { + regulator-name = "vcc3v3_sd"; + regulator-always-on; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + }; + }; +}; + + +&i2c5 { + status = "okay"; + + hym8563: hym8563@51 { + compatible = "haoyu,hym8563"; + reg = <0x51>; + pinctrl-names = "default"; + pinctrl-0 = <&rtc_int>; + interrupt-parent = <&gpio0>; + interrupts = ; + wakeup-source; + }; +}; + +&i2s0_8ch { + status = "okay"; +}; + +&i2s1_8ch { + rockchip,trcm-sync-tx-only; + status = "okay"; +}; + + +&mdio0 { + rgmii_phy0: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0x1>; + interrupt-parent = <&gpio0>; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&gmac_int>; + }; +}; + +&pcie30phy { + data-lanes = <1 2>; + status = "okay"; +}; + +&pcie3x1 { + num-lanes = <1>; + reset-gpios = <&gpio3 RK_PA1 GPIO_ACTIVE_HIGH>; + vpcie3v3-supply = <&vcc3v3_ngff>; + status = "okay"; +}; + +&pcie3x2 { + num-lanes = <1>; + reset-gpios = <&gpio2 RK_PD6 GPIO_ACTIVE_HIGH>; + vpcie3v3-supply = <&vcc3v3_pcie>; + status = "okay"; +}; + +&pcie2x1 { + num-viewport = <4>; + reset-gpios = <&gpio0 RK_PB6 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; + +&pinctrl { + gpio-leds { + + sys_led_pin: sys-led-pin { + rockchip,pins = <4 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + wan_led_pin: wan-led-pin { + rockchip,pins = <2 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + lan1_led_pin: lan1-led-pin { + rockchip,pins = <3 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + lan2_led_pin: lan2-led-pin { + rockchip,pins = <3 RK_PD7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + gmac { + gmac_int: gmac-int { + rockchip,pins = <0 RK_PC4 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + gpio-key { + key1_pin: key1-pin { + rockchip,pins = <4 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + pmic { + pmic_int: pmic_int { + rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + rtc { + rtc_int: rtc-int { + rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + usb { + vcc5v0_usb_host_en: vcc5v0-usb-host-en { + rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + vcc5v0_usb_otg_en: vcc5v0-usb-otg-en { + rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&pmu_io_domains { + pmuio1-supply = <&vcc3v3_pmu>; + pmuio2-supply = <&vcc3v3_pmu>; + vccio1-supply = <&vccio_acodec>; + vccio3-supply = <&vccio_sd>; + vccio4-supply = <&vcc_1v8>; + vccio5-supply = <&vcc_3v3>; + vccio6-supply = <&vcc_1v8>; + vccio7-supply = <&vcc_3v3>; + status = "okay"; +}; + +&pwm0 { + status = "okay"; +}; + +&pwm4 { + status = "disabled"; +}; + +&pwm5 { + status = "disabled"; +}; + +&pwm7 { + status = "disabled"; +}; + +&saradc { + vref-supply = <&vcca_1v8>; + status = "okay"; +}; + +&sata2 { + status = "disabled"; +}; + +&sdhci { + bus-width = <8>; + non-removable; + max-frequency = <200000000>; + pinctrl-names = "default"; + pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd>; + status = "okay"; +}; + +&sdmmc0 { + max-frequency = <150000000>; + no-sdio; + no-mmc; + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + disable-wp; + sd-uhs-sdr104; + vmmc-supply = <&vcc3v3_sd>; + vqmmc-supply = <&vccio_sd>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>; + status = "okay"; +}; + +&spi3 { + pinctrl-0 = <&spi3m1_pins>; + status = "disabled"; +}; + +&tsadc { + rockchip,hw-tshut-mode = <1>; + rockchip,hw-tshut-polarity = <0>; + status = "okay"; +}; + +&uart0 { + status = "disabled"; +}; + +&uart2 { + status = "okay"; +}; + +&uart7 { + pinctrl-0 = <&uart7m1_xfer>; + status = "disabled"; +}; + +&uart9 { + pinctrl-0 = <&uart9m1_xfer>; + status = "disabled"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; + +&usb_host0_xhci { + dr_mode = "host"; + status = "okay"; +}; + +&usb_host1_ehci { + status = "okay"; +}; + +&usb_host1_ohci { + status = "okay"; +}; + +&usb_host1_xhci { + status = "okay"; +}; + +&usb2phy0 { + status = "okay"; +}; + +&usb2phy0_host { + phy-supply = <&vcc5v0_usb_host>; + status = "okay"; +}; + +&usb2phy0_otg { + phy-supply = <&vcc5v0_usb_otg>; + status = "okay"; +}; + +&usb2phy1 { + status = "okay"; +}; + +&usb2phy1_host { + status = "okay"; +}; + +&usb2phy1_otg { + status = "okay"; +}; + +&vop { + assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>; + assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>; + status = "okay"; +}; + +&vop_mmu { + status = "okay"; +}; + +&vp0 { + vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { + reg = ; + remote-endpoint = <&hdmi_in_vp0>; + }; +}; \ No newline at end of file diff --git a/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-r66s.dts b/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-r66s.dts index 1f7dde482..f67999762 100644 --- a/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-r66s.dts +++ b/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-r66s.dts @@ -1,9 +1,530 @@ -// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT /dts-v1/; +#include +#include +#include +#include +#include "rk3568.dtsi" / { model = "FastRhino R66S"; compatible = "fastrhino,r66s", "rockchip,rk3568"; + + aliases { + ethernet0 = &rtl8125_1; + ethernet1 = &rtl8125_2; + led-boot = &power_led; + led-failsafe = &power_led; + led-running = &power_led; + led-upgrade = &power_led; + mmc0 = &sdmmc0; + }; + + chosen: chosen { + stdout-path = "serial2:1500000n8"; + }; + + gpio-keys { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&reset_button_pin>; + + reset { + debounce-interval = <50>; + gpios = <&gpio0 RK_PB6 GPIO_ACTIVE_LOW>; + label = "reset"; + linux,code = ; + }; + }; + + gpio-leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&power_led_pin>; + + power_led: led-power { + label = "green:power"; + gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_HIGH>; + }; + }; + + dc_12v: dc-12v { + compatible = "regulator-fixed"; + regulator-name = "dc_12v"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + }; + + vcc3v3_pcie: vcc3v3-pcie { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_pcie"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc5v0_sys>; + }; + + vcc3v3_sys: vcc3v3-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&dc_12v>; + }; + + vcc5v0_sys: vcc5v0-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&dc_12v>; + }; + + vcc5v0_usb_host: vcc5v0-usb-host { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_usb_host"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + vcc5v0_usb_otg: vcc5v0-usb-otg { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc5v0_usb_otg_en>; + regulator-name = "vcc5v0_usb_otg"; + regulator-always-on; + regulator-boot-on; + }; }; +&combphy0 { + status = "okay"; +}; + +&combphy1 { + status = "okay"; +}; + +&cpu0 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu1 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu2 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu3 { + cpu-supply = <&vdd_cpu>; +}; + +&gpu { + mali-supply = <&vdd_gpu>; + status = "okay"; +}; + +&i2c0 { + status = "okay"; + + vdd_cpu: regulator@1c { + compatible = "tcs,tcs4525"; + reg = <0x1c>; + fcs,suspend-voltage-selector = <1>; + regulator-name = "vdd_cpu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1150000>; + regulator-ramp-delay = <2300>; + vin-supply = <&vcc5v0_sys>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + rk809: pmic@20 { + compatible = "rockchip,rk809"; + reg = <0x20>; + interrupt-parent = <&gpio0>; + interrupts = ; + #clock-cells = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int>; + rockchip,system-power-controller; + vcc1-supply = <&vcc3v3_sys>; + vcc2-supply = <&vcc3v3_sys>; + vcc3-supply = <&vcc3v3_sys>; + vcc4-supply = <&vcc3v3_sys>; + vcc5-supply = <&vcc3v3_sys>; + vcc6-supply = <&vcc3v3_sys>; + vcc7-supply = <&vcc3v3_sys>; + vcc8-supply = <&vcc3v3_sys>; + vcc9-supply = <&vcc3v3_sys>; + wakeup-source; + + regulators { + vdd_logic: DCDC_REG1 { + regulator-name = "vdd_logic"; + regulator-always-on; + regulator-boot-on; + regulator-init-microvolt = <900000>; + regulator-initial-mode = <0x2>; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_gpu: DCDC_REG2 { + regulator-name = "vdd_gpu"; + regulator-always-on; + regulator-init-microvolt = <900000>; + regulator-initial-mode = <0x2>; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <0x2>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vdd_npu: DCDC_REG4 { + regulator-name = "vdd_npu"; + regulator-init-microvolt = <900000>; + regulator-initial-mode = <0x2>; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_1v8: DCDC_REG5 { + regulator-name = "vcc_1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda0v9_image: LDO_REG1 { + regulator-name = "vdda0v9_image"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <950000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda_0v9: LDO_REG2 { + regulator-name = "vdda_0v9"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda0v9_pmu: LDO_REG3 { + regulator-name = "vdda0v9_pmu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <900000>; + }; + }; + + vccio_acodec: LDO_REG4 { + regulator-name = "vccio_acodec"; + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vccio_sd: LDO_REG5 { + regulator-name = "vccio_sd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc3v3_pmu: LDO_REG6 { + regulator-name = "vcc3v3_pmu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcca_1v8: LDO_REG7 { + regulator-name = "vcca_1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcca1v8_pmu: LDO_REG8 { + regulator-name = "vcca1v8_pmu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcca1v8_image: LDO_REG9 { + regulator-name = "vcca1v8_image"; + regulator-init-microvolt = <950000>; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vcc_3v3: SWITCH_REG1 { + regulator-name = "vcc_3v3"; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc3v3_sd: SWITCH_REG2 { + regulator-name = "vcc3v3_sd"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + }; + + }; +}; + +&pcie30phy { + data-lanes = <1 2>; + status = "okay"; +}; + +&pcie3x1 { + num-lanes = <1>; + reset-gpios = <&gpio0 RK_PC3 GPIO_ACTIVE_HIGH>; + vpcie3v3-supply = <&vcc3v3_pcie>; + status = "okay"; + + pcie@10 { + reg = <0x00100000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + + rtl8125_1: pcie-eth@10,0 { + compatible = "pci10ec,8125"; + reg = <0x000000 0 0 0 0>; + + realtek,led-data = <0x4078>; + }; + }; +}; + +&pcie3x2 { + num-lanes = <1>; + reset-gpios = <&gpio0 RK_PC6 GPIO_ACTIVE_HIGH>; + vpcie3v3-supply = <&vcc3v3_pcie>; + status = "okay"; + + pcie@20 { + reg = <0x00200000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + + rtl8125_2: pcie-eth@20,0 { + compatible = "pci10ec,8125"; + reg = <0x000000 0 0 0 0>; + + realtek,led-data = <0x4078>; + }; + }; +}; + +&pinctrl { + gpio-leds { + power_led_pin: power-led-pin { + rockchip,pins = <0 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pmic { + pmic_int: pmic_int { + rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + rockchip-key { + reset_button_pin: reset-button-pin { + rockchip,pins = <0 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + usb { + vcc5v0_usb_otg_en: vcc5v0_usb_otg_en { + rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&pmu_io_domains { + pmuio1-supply = <&vcc3v3_pmu>; + pmuio2-supply = <&vcc3v3_pmu>; + vccio1-supply = <&vccio_acodec>; + vccio3-supply = <&vccio_sd>; + vccio4-supply = <&vcc_1v8>; + vccio5-supply = <&vcc_3v3>; + vccio6-supply = <&vcc_1v8>; + vccio7-supply = <&vcc_3v3>; + status = "okay"; +}; + +&rng { + status = "okay"; +}; + +&saradc { + vref-supply = <&vcca_1v8>; + status = "okay"; +}; + +&sdmmc0 { + max-frequency = <150000000>; + no-sdio; + no-mmc; + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + disable-wp; + vmmc-supply = <&vcc3v3_sd>; + vqmmc-supply = <&vccio_sd>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>; + status = "okay"; +}; + +&tsadc { + rockchip,hw-tshut-mode = <1>; + rockchip,hw-tshut-polarity = <0>; + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; + +&usb_host0_xhci { + extcon = <&usb2phy0>; + dr_mode = "host"; + status = "okay"; +}; + +&usb_host1_ehci { + status = "okay"; +}; + +&usb_host1_ohci { + status = "okay"; +}; + +&usb_host1_xhci { + status = "okay"; +}; + +&usb2phy0 { + status = "okay"; +}; + +&usb2phy0_host { + phy-supply = <&vcc5v0_usb_host>; + status = "okay"; +}; + +&usb2phy0_otg { + phy-supply = <&vcc5v0_usb_otg>; + status = "okay"; +}; diff --git a/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts b/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts index 3cb836125..6b5093a1a 100644 --- a/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts +++ b/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts @@ -1,8 +1,617 @@ // SPDX-License-Identifier: (GPL-2.0+ OR MIT) /dts-v1/; +#include +#include +#include +#include +#include "rk3568.dtsi" / { model = "Radxa ROCK3 Model A"; compatible = "radxa,rock3a", "rockchip,rk3568"; + + aliases { + ethernet0 = &gmac1; + mmc0 = &sdmmc0; + mmc1 = &sdhci; + }; + + chosen: chosen { + stdout-path = "serial2:1500000n8"; + }; + + hdmi-con { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_con_in: endpoint { + remote-endpoint = <&hdmi_out_con>; + }; + }; + }; + + leds { + compatible = "gpio-leds"; + + led_user: led-0 { + gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>; + function = LED_FUNCTION_HEARTBEAT; + color = ; + linux,default-trigger = "heartbeat"; + pinctrl-names = "default"; + pinctrl-0 = <&led_user_en>; + }; + }; + + rk809-sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,name = "Analog RK809"; + simple-audio-card,mclk-fs = <256>; + + simple-audio-card,cpu { + sound-dai = <&i2s1_8ch>; + }; + + simple-audio-card,codec { + sound-dai = <&rk809>; + }; + }; + + vcc12v_dcin: vcc12v-dcin { + compatible = "regulator-fixed"; + regulator-name = "vcc12v_dcin"; + regulator-always-on; + regulator-boot-on; + }; + + vcc3v3_sys: vcc3v3-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc12v_dcin>; + }; + + vcc5v0_sys: vcc5v0-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc12v_dcin>; + }; + + vcc5v0_usb: vcc5v0-usb { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_usb"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc12v_dcin>; + }; + + vcc5v0_usb_host: vcc5v0-usb-host { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc5v0_usb_host_en>; + regulator-name = "vcc5v0_usb_host"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc5v0_usb>; + }; + + vcc5v0_usb_hub: vcc5v0-usb-hub-regulator { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 RK_PD5 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc5v0_usb_hub_en>; + regulator-name = "vcc5v0_usb_hub"; + regulator-always-on; + vin-supply = <&vcc5v0_usb>; + }; + + vcc5v0_usb_otg: vcc5v0-usb-otg-regulator { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc5v0_usb_otg_en>; + regulator-name = "vcc5v0_usb_otg"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc5v0_usb>; + }; +}; + +&combphy0 { + status = "okay"; +}; + +&combphy1 { + status = "okay"; +}; + +&cpu0 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu1 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu2 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu3 { + cpu-supply = <&vdd_cpu>; +}; + +&gmac1 { + assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>; + assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>; + assigned-clock-rates = <0>, <125000000>; + clock_in_out = "output"; + phy-handle = <&rgmii_phy1>; + phy-mode = "rgmii-id"; + pinctrl-names = "default"; + pinctrl-0 = <&gmac1m1_miim + &gmac1m1_tx_bus2 + &gmac1m1_rx_bus2 + &gmac1m1_rgmii_clk + &gmac1m1_rgmii_bus>; + status = "okay"; +}; + +&gpu { + mali-supply = <&vdd_gpu>; + status = "okay"; +}; + +&hdmi { + avdd-0v9-supply = <&vdda0v9_image>; + avdd-1v8-supply = <&vcca1v8_image>; + status = "okay"; +}; + +&hdmi_in { + hdmi_in_vp0: endpoint { + remote-endpoint = <&vp0_out_hdmi>; + }; +}; + +&hdmi_out { + hdmi_out_con: endpoint { + remote-endpoint = <&hdmi_con_in>; + }; +}; + +&hdmi_sound { + status = "okay"; +}; + +&i2c0 { + status = "okay"; + + vdd_cpu: regulator@1c { + compatible = "tcs,tcs4525"; + reg = <0x1c>; + fcs,suspend-voltage-selector = <1>; + regulator-name = "vdd_cpu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1150000>; + regulator-ramp-delay = <2300>; + vin-supply = <&vcc5v0_sys>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + rk809: pmic@20 { + compatible = "rockchip,rk809"; + reg = <0x20>; + interrupt-parent = <&gpio0>; + interrupts = ; + assigned-clocks = <&cru I2S1_MCLKOUT_TX>; + assigned-clock-parents = <&cru CLK_I2S1_8CH_TX>; + #clock-cells = <1>; + clock-names = "mclk"; + clocks = <&cru I2S1_MCLKOUT_TX>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int>, <&i2s1m0_mclk>; + rockchip,system-power-controller; + #sound-dai-cells = <0>; + vcc1-supply = <&vcc3v3_sys>; + vcc2-supply = <&vcc3v3_sys>; + vcc3-supply = <&vcc3v3_sys>; + vcc4-supply = <&vcc3v3_sys>; + vcc5-supply = <&vcc3v3_sys>; + vcc6-supply = <&vcc3v3_sys>; + vcc7-supply = <&vcc3v3_sys>; + vcc8-supply = <&vcc3v3_sys>; + vcc9-supply = <&vcc3v3_sys>; + wakeup-source; + + regulators { + vdd_logic: DCDC_REG1 { + regulator-name = "vdd_logic"; + regulator-always-on; + regulator-boot-on; + regulator-init-microvolt = <900000>; + regulator-initial-mode = <0x2>; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_gpu: DCDC_REG2 { + regulator-name = "vdd_gpu"; + regulator-always-on; + regulator-init-microvolt = <900000>; + regulator-initial-mode = <0x2>; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <0x2>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vdd_npu: DCDC_REG4 { + regulator-name = "vdd_npu"; + regulator-init-microvolt = <900000>; + regulator-initial-mode = <0x2>; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_1v8: DCDC_REG5 { + regulator-name = "vcc_1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda0v9_image: LDO_REG1 { + regulator-name = "vdda0v9_image"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda_0v9: LDO_REG2 { + regulator-name = "vdda_0v9"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda0v9_pmu: LDO_REG3 { + regulator-name = "vdda0v9_pmu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <900000>; + }; + }; + + vccio_acodec: LDO_REG4 { + regulator-name = "vccio_acodec"; + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vccio_sd: LDO_REG5 { + regulator-name = "vccio_sd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc3v3_pmu: LDO_REG6 { + regulator-name = "vcc3v3_pmu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcca_1v8: LDO_REG7 { + regulator-name = "vcca_1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcca1v8_pmu: LDO_REG8 { + regulator-name = "vcca1v8_pmu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcca1v8_image: LDO_REG9 { + regulator-name = "vcca1v8_image"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_3v3: SWITCH_REG1 { + regulator-name = "vcc_3v3"; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc3v3_sd: SWITCH_REG2 { + regulator-name = "vcc3v3_sd"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + }; + + codec { + mic-in-differential; + }; + }; +}; + +&i2s0_8ch { + status = "okay"; +}; + +&i2s1_8ch { + rockchip,trcm-sync-tx-only; + status = "okay"; +}; + +&mdio1 { + rgmii_phy1: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0x0>; + pinctrl-names = "default"; + pinctrl-0 = <ð_phy_rst>; + reset-assert-us = <20000>; + reset-deassert-us = <100000>; + reset-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>; + }; +}; + +&pinctrl { + ethernet { + eth_phy_rst: eth_phy_rst { + rockchip,pins = <3 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + leds { + led_user_en: led_user_en { + rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pmic { + pmic_int: pmic_int { + rockchip,pins = + <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + usb { + vcc5v0_usb_host_en: vcc5v0_usb_host_en { + rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + vcc5v0_usb_hub_en: vcc5v0_usb_hub_en { + rockchip,pins = <0 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + vcc5v0_usb_otg_en: vcc5v0_usb_otg_en { + rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&pmu_io_domains { + pmuio1-supply = <&vcc3v3_pmu>; + pmuio2-supply = <&vcc3v3_pmu>; + vccio1-supply = <&vccio_acodec>; + vccio2-supply = <&vcc_1v8>; + vccio3-supply = <&vccio_sd>; + vccio4-supply = <&vcc_1v8>; + vccio5-supply = <&vcc_3v3>; + vccio6-supply = <&vcc_1v8>; + vccio7-supply = <&vcc_3v3>; + status = "okay"; +}; + +&saradc { + vref-supply = <&vcca_1v8>; + status = "okay"; +}; + +&sdhci { + bus-width = <8>; + max-frequency = <200000000>; + non-removable; + pinctrl-names = "default"; + pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>; + vmmc-supply = <&vcc_3v3>; + vqmmc-supply = <&vcc_1v8>; + status = "okay"; +}; + +&sdmmc0 { + bus-width = <4>; + cap-sd-highspeed; + cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; + disable-wp; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>; + sd-uhs-sdr104; + vmmc-supply = <&vcc3v3_sd>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +}; + +&tsadc { + rockchip,hw-tshut-mode = <1>; + rockchip,hw-tshut-polarity = <0>; + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; + +&usb_host0_xhci { + extcon = <&usb2phy0>; + status = "okay"; +}; + +&usb_host1_ehci { + status = "okay"; +}; + +&usb_host1_ohci { + status = "okay"; +}; + +&usb_host1_xhci { + status = "okay"; +}; + +&usb2phy0 { + status = "okay"; +}; + +&usb2phy0_host { + phy-supply = <&vcc5v0_usb_host>; + status = "okay"; +}; + +&usb2phy0_otg { + vbus-supply = <&vcc5v0_usb_otg>; + status = "okay"; +}; + +&usb2phy1 { + status = "okay"; +}; + +&usb2phy1_host { + phy-supply = <&vcc5v0_usb_host>; + status = "okay"; +}; + +&usb2phy1_otg { + phy-supply = <&vcc5v0_usb_host>; + status = "okay"; +}; + +&vop { + assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>; + assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>; + status = "okay"; +}; + +&vop_mmu { + status = "okay"; +}; + +&vp0 { + vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { + reg = ; + remote-endpoint = <&hdmi_in_vp0>; + }; }; diff --git a/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-station-p2.dts b/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-station-p2.dts index e24846eff..3883c1827 100644 --- a/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-station-p2.dts +++ b/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-station-p2.dts @@ -1,9 +1,787 @@ // SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2021 Rockchip Electronics Co., Ltd. + * + */ /dts-v1/; +#include +#include +#include +#include "rk3568.dtsi" + / { model = "Firefly Station P2"; compatible = "firefly,rk3568-roc-pc", "rockchip,rk3568"; + + aliases { + ethernet0 = &gmac0; + ethernet1 = &gmac1; + mmc0 = &sdmmc0; + mmc1 = &sdhci; + }; + + chosen: chosen { + stdout-path = "serial2:1500000n8"; + }; + + gmac0_clkin: external-gmac0-clock { + compatible = "fixed-clock"; + clock-frequency = <125000000>; + clock-output-names = "gmac0_clkin"; + #clock-cells = <0>; + }; + + gmac1_clkin: external-gmac1-clock { + compatible = "fixed-clock"; + clock-frequency = <125000000>; + clock-output-names = "gmac1_clkin"; + #clock-cells = <0>; + }; + + leds { + compatible = "gpio-leds"; + + power_led: power { + label = "firefly:blue:power"; + linux,default-trigger = "ir-power-click"; + default-state = "on"; + gpios = <&gpio1 RK_PB2 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&led_power>; + }; + + user_led: user { + label = "firefly:yellow:user"; + linux,default-trigger = "ir-user-click"; + default-state = "off"; + gpios = <&gpio1 RK_PB1 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&led_user>; + }; + }; + + hdmi-con { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_con_in: endpoint { + remote-endpoint = <&hdmi_out_con>; + }; + }; + }; + + sdio_pwrseq: sdio-pwrseq { + status = "okay"; + compatible = "mmc-pwrseq-simple"; + clocks = <&rk809 1>; + clock-names = "ext_clock"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_enable_h>; + reset-gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_LOW>; + post-power-on-delay-ms = <100>; + }; + + dc_12v: dc-12v { + compatible = "regulator-fixed"; + regulator-name = "dc_12v"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + }; + + vcc3v3_sys: vcc3v3-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&dc_12v>; + }; + + vcc5v0_sys: vcc5v0-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&dc_12v>; + }; + + vcc5v0_usb: vcc5v0-usb { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_usb"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&dc_12v>; + }; + + pcie30_avdd0v9: pcie30-avdd0v9 { + compatible = "regulator-fixed"; + regulator-name = "pcie30_avdd0v9"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + vin-supply = <&vcc3v3_sys>; + }; + + pcie30_avdd1v8: pcie30-avdd1v8 { + compatible = "regulator-fixed"; + regulator-name = "pcie30_avdd1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc3v3_sys>; + }; + + vcc3v3_pcie: vcc3v3_pi6c: vcc3v3-pcie { + compatible = "regulator-fixed"; + regulator-always-on; + enable-active-high; + gpio = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pcie_enable_h>; + regulator-name = "vcc3v3_pcie"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc5v0_sys>; + }; + + vcc5v0_host: vcc5v0-host { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_host"; + enable-active-high; + gpio = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc5v0_host_en>; + regulator-always-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc5v0_usb>; + }; + + vcc5v0_otg: vcc5v0-otg { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_otg"; + enable-active-high; + gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc5v0_otg_en>; + vin-supply = <&vcc5v0_usb>; + }; + + vcc_hub_reset: vcc-hub-reset { + compatible = "regulator-fixed"; + regulator-name = "vcc_hub_reset"; + enable-active-high; + gpio = <&gpio1 RK_PA4 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc_hub_reset_en>; + regulator-always-on; + }; + + pcie_pi6c_oe: pcie-pi6c-oe { + compatible = "regulator-fixed"; + regulator-name = "pcie_pi6c_oe_en"; + gpio = <&gpio3 RK_PA7 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&pcie_pi6c_oe_en>; + regulator-always-on; + }; + + vcc3v3_lcd0_n: vcc3v3-lcd0-n { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_lcd0_n"; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc3v3_lcd1_n: vcc3v3-lcd1-n { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_lcd1_n"; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; }; +&gmac0 { + phy-mode = "rgmii"; + clock_in_out = "input"; + + snps,reset-gpio = <&gpio2 RK_PD3 GPIO_ACTIVE_LOW>; + snps,reset-active-low; + /* Reset time is 20ms, 100ms for rtl8211f */ + snps,reset-delays-us = <0 20000 100000>; + + assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>; + assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>, <&gmac0_clkin>; + + pinctrl-names = "default"; + pinctrl-0 = <&gmac0_miim + &gmac0_tx_bus2 + &gmac0_rx_bus2 + &gmac0_rgmii_clk + &gmac0_rgmii_bus + &gmac0_clkinout>; + + tx_delay = <0x3c>; + rx_delay = <0x2f>; + + phy-handle = <&rgmii_phy0>; + status = "okay"; +}; + +&gmac1 { + phy-mode = "rgmii"; + clock_in_out = "input"; + + snps,reset-gpio = <&gpio2 RK_PD1 GPIO_ACTIVE_LOW>; + snps,reset-active-low; + /* Reset time is 20ms, 100ms for rtl8211f */ + snps,reset-delays-us = <0 20000 100000>; + + assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>; + assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&gmac1_clkin>; + + pinctrl-names = "default"; + pinctrl-0 = <&gmac1m1_miim + &gmac1m1_tx_bus2 + &gmac1m1_rx_bus2 + &gmac1m1_rgmii_clk + &gmac1m1_rgmii_bus + &gmac1m1_clkinout>; + + tx_delay = <0x4f>; + rx_delay = <0x26>; + + phy-handle = <&rgmii_phy1>; + status = "okay"; +}; + +&hdmi { + status = "okay"; + avdd-0v9-supply = <&vdda0v9_image>; + avdd-1v8-supply = <&vcca1v8_image>; +}; + +&i2c0 { + status = "okay"; + + vdd_cpu: regulator@1c { + compatible = "tcs,tcs4525"; + reg = <0x1c>; + fcs,suspend-voltage-selector = <1>; + regulator-name = "vdd_cpu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1150000>; + regulator-ramp-delay = <2300>; + vin-supply = <&vcc5v0_sys>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + rk809: pmic@20 { + compatible = "rockchip,rk809"; + reg = <0x20>; + interrupt-parent = <&gpio0>; + interrupts = ; + assigned-clocks = <&cru I2S1_MCLKOUT_TX>; + assigned-clock-parents = <&cru CLK_I2S1_8CH_TX>; + #clock-cells = <1>; + clock-names = "mclk"; + clocks = <&cru I2S1_MCLKOUT_TX>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int>; + rockchip,system-power-controller; + #sound-dai-cells = <0>; + vcc1-supply = <&vcc3v3_sys>; + vcc2-supply = <&vcc3v3_sys>; + vcc3-supply = <&vcc3v3_sys>; + vcc4-supply = <&vcc3v3_sys>; + vcc5-supply = <&vcc3v3_sys>; + vcc6-supply = <&vcc3v3_sys>; + vcc7-supply = <&vcc3v3_sys>; + vcc8-supply = <&vcc3v3_sys>; + vcc9-supply = <&vcc3v3_sys>; + wakeup-source; + + regulators { + vdd_logic: DCDC_REG1 { + regulator-name = "vdd_logic"; + regulator-always-on; + regulator-boot-on; + regulator-init-microvolt = <900000>; + regulator-initial-mode = <0x2>; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_gpu: DCDC_REG2 { + regulator-name = "vdd_gpu"; + regulator-always-on; + regulator-init-microvolt = <900000>; + regulator-initial-mode = <0x2>; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <0x2>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vdd_npu: DCDC_REG4 { + regulator-name = "vdd_npu"; + regulator-init-microvolt = <900000>; + regulator-initial-mode = <0x2>; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_1v8: DCDC_REG5 { + regulator-name = "vcc_1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda0v9_image: LDO_REG1 { + regulator-name = "vdda0v9_image"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda_0v9: LDO_REG2 { + regulator-name = "vdda_0v9"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda0v9_pmu: LDO_REG3 { + regulator-name = "vdda0v9_pmu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <900000>; + }; + }; + + vccio_acodec: LDO_REG4 { + regulator-name = "vccio_acodec"; + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vccio_sd: LDO_REG5 { + regulator-name = "vccio_sd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc3v3_pmu: LDO_REG6 { + regulator-name = "vcc3v3_pmu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcca_1v8: LDO_REG7 { + regulator-name = "vcca_1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcca1v8_pmu: LDO_REG8 { + regulator-name = "vcca1v8_pmu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcca1v8_image: LDO_REG9 { + regulator-name = "vcca1v8_image"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_3v3: SWITCH_REG1 { + regulator-name = "vcc_3v3"; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc3v3_sd: SWITCH_REG2 { + regulator-name = "vcc3v3_sd"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + }; + }; +}; + +&mdio0 { + rgmii_phy0: phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0x0>; + }; +}; + +&mdio1 { + rgmii_phy1: phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0x0>; + }; +}; + +&pinctrl { + leds { + led_power: led-power { + rockchip,pins = <1 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + led_user: led-user { + rockchip,pins = <1 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + sdio-pwrseq { + wifi_enable_h: wifi-enable-h { + rockchip,pins = <3 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + usb { + vcc5v0_host_en: vcc5v0-host-en { + rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + vcc5v0_otg_en: vcc5v0-otg-en { + rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + vcc_hub_reset_en: vcc-hub-reset-en { + rockchip,pins = <1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + fusb0_int { + fusb0_int: fusb0-int { + rockchip,pins = <0 RK_PC1 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + + pcie { + pcie_enable_h: pcie-enable-h { + rockchip,pins = <0 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + pcie_reset_h: pcie-reset-h { + rockchip,pins = <2 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + pcie_pi6c_oe_en: pcie-pi6c-oe-en { + rockchip,pins = <3 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pmic { + pmic_int: pmic_int { + rockchip,pins = + <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; + +&i2s0_8ch { + status = "okay"; +}; + +&pmu_io_domains { + pmuio1-supply = <&vcc3v3_pmu>; + pmuio2-supply = <&vcc3v3_pmu>; + vccio1-supply = <&vccio_acodec>; + vccio2-supply = <&vcc_1v8>; + vccio3-supply = <&vccio_sd>; + vccio4-supply = <&vcc_1v8>; + vccio5-supply = <&vcc_3v3>; + vccio6-supply = <&vcc_1v8>; + vccio7-supply = <&vcc_3v3>; + status = "okay"; +}; + +&saradc { + vref-supply = <&vcca_1v8>; + status = "okay"; +}; + +&sdhci { + bus-width = <8>; + max-frequency = <200000000>; + non-removable; + pinctrl-names = "default"; + pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>; + status = "okay"; +}; + +&sdmmc0 { + bus-width = <4>; + cap-sd-highspeed; + cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; + disable-wp; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>; + sd-uhs-sdr104; + vmmc-supply = <&vcc3v3_sd>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +}; + +&sdmmc2 { + max-frequency = <150000000>; + supports-sdio; + bus-width = <4>; + disable-wp; + cap-sd-highspeed; + cap-sdio-irq; + keep-power-in-suspend; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc2m0_bus4 &sdmmc2m0_cmd &sdmmc2m0_clk>; + sd-uhs-sdr104; + mmc-pwrseq = <&sdio_pwrseq>; + non-removable; + status = "okay"; +}; + +&tsadc { + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&vop { + status = "okay"; + assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>; + assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>; +}; + +&vop_mmu { + status = "okay"; +}; + +&hdmi_in { + hdmi_in_vp0: endpoint@0 { + reg = <0>; + remote-endpoint = <&vp0_out_hdmi>; + }; +}; + +&vp0 { + vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { + reg = ; + remote-endpoint = <&hdmi_in_vp0>; + }; +}; + +&hdmi_out { + hdmi_out_con: endpoint { + remote-endpoint = <&hdmi_con_in>; + }; +}; + +&hdmi_sound { + status = "okay"; +}; + +&cpu0 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu1 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu2 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu3 { + cpu-supply = <&vdd_cpu>; +}; + +&gpu { + mali-supply = <&vdd_gpu>; + status = "okay"; +}; + +&combphy0 { + status = "okay"; +}; + +&combphy1 { + status = "okay"; +}; + +&combphy2 { + status = "okay"; +}; + +&sata2 { + status = "okay"; +}; + +&pcie30phy { + status = "okay"; +}; + +&pcie3x2{ + pinctrl-names = "default"; + pinctrl-0 = <&pcie_reset_h>; + reset-gpios = <&gpio2 RK_PD6 GPIO_ACTIVE_HIGH>; + vpcie3v3-supply = <&vcc3v3_pcie>; + status = "okay"; +}; + +&usb2phy0_host { + phy-supply = <&vcc5v0_host>; + status = "okay"; +}; + +&usb2phy1_host { + phy-supply = <&vcc5v0_host>; + status = "okay"; +}; + +&usb2phy1_otg { + phy-supply = <&vcc5v0_host>; + status = "okay"; +}; + +&usb2phy0 { + status = "okay"; +}; + +&usb2phy1 { + status = "okay"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; + +&usb_host0_xhci { + extcon = <&usb2phy0>; + status = "okay"; +}; + +&usb_host1_ehci { + status = "okay"; +}; + +&usb_host1_ohci { + status = "okay"; +}; + +&usb_host1_xhci { + status = "okay"; +}; diff --git a/target/linux/rockchip/files/drivers/phy/rockchip/p3phy.fw b/target/linux/rockchip/files/drivers/phy/rockchip/p3phy.fw new file mode 100644 index 000000000..301c42837 --- /dev/null +++ b/target/linux/rockchip/files/drivers/phy/rockchip/p3phy.fw @@ -0,0 +1,8192 @@ +0x081D, +0xFFFF, +0x33AF, +0x33AE, +0x0C4F, +0xD10D, +0x0D0F, +0xD306, +0x0C8F, +0xDB06, +0x33AF, +0xD38D, +0x01AC, +0x2000, +0x0C1E, +0x014A, +0x2800, +0x1B80, +0xA0B2, +0x0806, +0x0016, +0x8CC7, +0xD1AE, +0x0C2E, +0x1B75, +0x33AE, +0xA01C, +0x8026, +0x0C2F, +0xD375, +0x33AF, +0x1B81, +0xA022, +0x8026, +0x0D8F, +0x03A6, +0x0003, +0x33AF, +0x0C6F, +0xDBA6, +0x33AF, +0x0C4F, +0xD10D, +0x33AF, +0x0D8F, +0xDBA6, +0x33AF, +0x1B81, +0xA032, +0x8048, +0xDB87, +0x038D, +0x0020, +0xD310, +0x080F, +0x0020, +0xD106, +0x33AF, +0xDB8B, +0xDB8C, +0x1B0F, +0xA03A, +0x0807, +0x0044, +0x33FE, +0x0C01, +0x0C3F, +0x80BA, +0x0C4F, +0xD30E, +0x33AF, +0xD38D, +0x1B82, +0xA04B, +0x8061, +0xDB88, +0x080F, +0x0020, +0xD106, +0x33AF, +0x1B8E, +0xA053, +0x8061, +0x1BA7, +0xA056, +0x8053, +0x0807, +0x005C, +0x33FE, +0x0C01, +0x0C3F, +0x80BA, +0xDB8F, +0x0C2E, +0x1B09, +0xA05D, +0x33AE, +0x1B86, +0xA07B, +0x1B85, +0xA0A7, +0x080E, +0x0200, +0x1BF6, +0x33AE, +0xA074, +0x1B5E, +0xA06D, +0x8077, +0x0C4E, +0x1BF6, +0x33AE, +0xA077, +0x0806, +0x0000, +0x89A4, +0x0C4F, +0xDBF6, +0x33AF, +0x1B2F, +0xA07A, +0x89DF, +0x8000, +0x080F, +0x0020, +0xD106, +0x33AF, +0x0807, +0x0085, +0x33FE, +0x0C01, +0x0C3F, +0x80BA, +0xD35E, +0x038D, +0x0020, +0xD10D, +0x010D, +0x0002, +0x0C8F, +0xDB06, +0x33AF, +0x0D0F, +0xDB06, +0x33AF, +0x0C2E, +0x1919, +0xA095, +0x8092, +0x33AE, +0x0C8F, +0xD306, +0x33AF, +0x0C2E, +0x1919, +0xA09D, +0x33AE, +0x0D0F, +0xD306, +0x33AF, +0xD10D, +0xD38D, +0xDB10, +0xDB8C, +0xDB8B, +0xD310, +0x8000, +0xDB8B, +0xD35E, +0x0806, +0x0000, +0x1B28, +0xA995, +0x0806, +0x0000, +0x038D, +0x0020, +0x86F1, +0xD380, +0x1B59, +0xA19E, +0x80C8, +0x0C4F, +0xD3F6, +0x33AF, +0x080E, +0x01FC, +0x1BF6, +0x33AE, +0xA0C3, +0x080F, +0x01FC, +0x03F6, +0x0032, +0x33AF, +0x0806, +0x0157, +0x1B27, +0xA641, +0x822B, +0x0367, +0x003F, +0x0368, +0x0C09, +0x0369, +0x7928, +0xD36A, +0x036B, +0x007F, +0x036C, +0x0C13, +0x036D, +0x7803, +0xD36E, +0x037C, +0x003F, +0x037D, +0x0C01, +0x037E, +0x7818, +0xD37F, +0x03E0, +0x007F, +0x03E1, +0x0C2F, +0x03E2, +0x7828, +0x03E3, +0x36DC, +0x03E4, +0x007F, +0x03E5, +0x0C09, +0x03E6, +0x7818, +0x03E7, +0x124A, +0x080E, +0xFF00, +0x191E, +0x33AE, +0x080F, +0x00FF, +0x291D, +0x0CCF, +0xD11D, +0x080F, +0x0100, +0xD91D, +0x33AF, +0x0C2F, +0xD375, +0x33AF, +0x0349, +0x0017, +0x0353, +0x0017, +0x1B4A, +0x29B4, +0xD9B8, +0x0229, +0x1060, +0x022A, +0x0E24, +0x080E, +0x4000, +0x1B09, +0xA108, +0x0C2E, +0x1B02, +0xA10C, +0x33AE, +0xD317, +0x1B29, +0xA115, +0x705E, +0x8115, +0x1B2D, +0xA118, +0x811A, +0x014B, +0x2DAB, +0x1B2E, +0xA11D, +0x811F, +0x014C, +0x004B, +0x1B2A, +0xA123, +0x0125, +0x065A, +0x1B2B, +0xA126, +0x8128, +0x0127, +0x0D07, +0x0063, +0x7F00, +0x0073, +0x7F00, +0x1A28, +0xA145, +0xDA28, +0x1B29, +0xA137, +0x0060, +0x0008, +0x0070, +0x0008, +0xDBA8, +0x8140, +0x0C2F, +0xD881, +0x080F, +0xFFFF, +0xDBA8, +0x0061, +0x0018, +0x0071, +0x0018, +0x0301, +0x0F05, +0x03A0, +0x0007, +0x8147, +0x0301, +0x0F05, +0x1B2C, +0xA14C, +0x0144, +0x0100, +0x8152, +0x080F, +0x0200, +0xD944, +0x33AF, +0x0145, +0x6DB4, +0x0306, +0x0006, +0x1B0F, +0xA154, +0x80B6, +0x0305, +0x000C, +0x0306, +0x0007, +0x0317, +0x0003, +0x0306, +0x0006, +0x1B0F, +0xA15F, +0x0306, +0x0004, +0xDB87, +0x1A28, +0x5C6D, +0xA168, +0x816E, +0x13A3, +0x5CEC, +0xA168, +0x0228, +0x0003, +0x816E, +0x0C2E, +0x1A11, +0x33AE, +0xA177, +0x1867, +0x080C, +0x0100, +0x518D, +0x2B54, +0x0C4E, +0x1A11, +0x33AE, +0xA180, +0x1877, +0x080C, +0x0100, +0x518D, +0x2B55, +0x1867, +0x2868, +0x1877, +0x2878, +0x1886, +0x2B56, +0x1888, +0x2B58, +0x1887, +0x2B57, +0x0060, +0x0018, +0x0070, +0x0018, +0xDA12, +0xD3A0, +0xD3A8, +0xDB59, +0x7005, +0x0C4F, +0xD081, +0x080F, +0xFFFF, +0x0C8F, +0xD303, +0x33AF, +0x0C4F, +0xD30E, +0x33AF, +0x8000, +0x1B54, +0x2868, +0x1B55, +0x2878, +0x705E, +0x1B2D, +0xA1A6, +0x81A8, +0x014B, +0x2DAB, +0x1B2E, +0xA1AB, +0x81AD, +0x014C, +0x004B, +0x1B29, +0xA1B0, +0x81B8, +0x0C2F, +0xD881, +0x080F, +0xFFFF, +0x0061, +0x0018, +0x0071, +0x0018, +0x1B56, +0x2883, +0x1B58, +0x2885, +0x1B57, +0x2884, +0x0301, +0x0F05, +0xD9AE, +0x01AD, +0x0080, +0xD1AF, +0xD9B6, +0x1B40, +0x29AD, +0xD9AF, +0xD9B6, +0x1B41, +0x29AD, +0x01AF, +0x0002, +0xD9B6, +0x1B42, +0x29AD, +0x01AF, +0x0003, +0xD9B6, +0x1B45, +0x29AD, +0x01AF, +0x0014, +0xD9B6, +0x1B46, +0x29AD, +0x01AF, +0x0015, +0xD9B6, +0x01A8, +0x0140, +0x1B4B, +0x2973, +0x1B4C, +0x2974, +0x1B51, +0x2979, +0x1B4D, +0x2975, +0x1B4E, +0x2976, +0x1B52, +0x297A, +0x1BF2, +0x5C6D, +0xA1F1, +0x0C4F, +0xD9BA, +0x33AF, +0x0C8E, +0x1B24, +0x33AE, +0xA1F6, +0x81F9, +0x0C2F, +0xD9BA, +0x33AF, +0x1B4F, +0x080F, +0xFF00, +0x297F, +0x080F, +0xFFFF, +0x1B50, +0x080F, +0x00FF, +0x297F, +0x080F, +0xFFFF, +0x1B4A, +0x29B4, +0xD9B8, +0xD1AE, +0xD1A8, +0x018E, +0x0019, +0x0305, +0x000C, +0xD306, +0x1B0F, +0xA20F, +0x1B2C, +0xA214, +0x821A, +0x080F, +0x0200, +0xD944, +0x33AF, +0x0145, +0x6DB4, +0x1B04, +0xA21A, +0x1B2A, +0xA220, +0x0125, +0x065A, +0x1B2B, +0xA223, +0x8225, +0x0127, +0x0D07, +0xDA12, +0x0229, +0x1060, +0x022A, +0xE24 , +0x8193, +0x01A8, +0x0140, +0x0100, +0x0004, +0x018E, +0x0019, +0xD9AE, +0xD9B6, +0x01B0, +0x0B37, +0x01B1, +0x00FA, +0xD9B7, +0x0180, +0x03FF, +0xD981, +0xD182, +0xD183, +0x0184, +0x4000, +0x0185, +0x2408, +0x1B31, +0xA254, +0x01A8, +0x0140, +0xD1B5, +0x01AC, +0xA060, +0xD9AF, +0x0340, +0x0080, +0x0800, +0x0340, +0x01AD, +0x0080, +0xD9B6, +0x0807, +0x0254, +0x0C03, +0x864B, +0x1B31, +0xA268, +0x01A8, +0x0140, +0xD1B5, +0x01AC, +0xA080, +0x01AF, +0x0002, +0x0341, +0x0080, +0x0800, +0x0341, +0x01AD, +0x0080, +0xD9B6, +0x0807, +0x0268, +0x0C03, +0x864B, +0x01B1, +0x0062, +0xD9B7, +0x1B31, +0xA27E, +0x01A8, +0x0140, +0xD1B5, +0x01AC, +0xA080, +0xD9AF, +0x0340, +0x0080, +0x0800, +0x0340, +0x01AD, +0x0080, +0xD9B6, +0x0807, +0x027E, +0x0C03, +0x864B, +0x1B31, +0xA292, +0x01A8, +0x0140, +0xD1B5, +0x01AC, +0xA0C0, +0x01AF, +0x0003, +0x0342, +0x0080, +0x0800, +0x0342, +0x01AD, +0x0080, +0xD9B6, +0x0807, +0x0292, +0x0C03, +0x864B, +0x080E, +0xF800, +0x1B0C, +0x31A1, +0x080E, +0x07FF, +0x1B0C, +0x31A2, +0xD11D, +0x0CEE, +0x1B0D, +0x31A3, +0x33AE, +0x304D, +0x080F, +0x07FF, +0x29B0, +0x33AF, +0x302D, +0x080F, +0x00F8, +0x29B1, +0x33AF, +0x306D, +0x0CEF, +0x29B1, +0x33AF, +0xD9B7, +0x0C2E, +0x1BF6, +0x33AE, +0xA2CD, +0x0180, +0x03FF, +0xD981, +0xD182, +0xD183, +0x0184, +0x4000, +0x0185, +0x2408, +0x01A8, +0x0140, +0xD1B5, +0x01AC, +0xB080, +0x01AF, +0x0002, +0x03F7, +0x0080, +0x0800, +0x03F7, +0x01AD, +0x0080, +0xD9B6, +0x0807, +0x02CD, +0x0C03, +0x864B, +0x0C8E, +0x1BF4, +0x33AE, +0xA2EC, +0x0180, +0x03FF, +0xD981, +0xD182, +0xD183, +0x0184, +0x4000, +0x0185, +0x2408, +0x01A8, +0x0140, +0xD1B5, +0x01AC, +0xB0C0, +0x01AF, +0x0003, +0x03EC, +0x0080, +0x0800, +0x03EC, +0x01AD, +0x0080, +0xD9B6, +0x0807, +0x02EC, +0x0C03, +0x864B, +0x01B3, +0x0177, +0xD3F2, +0x0C2E, +0x1BF4, +0x33AE, +0xA313, +0x0180, +0x01FF, +0x0181, +0xAAAA, +0x0182, +0x2800, +0xD183, +0x0184, +0x6C00, +0x0185, +0x2408, +0x0807, +0x0301, +0x8DC7, +0x01A8, +0x0140, +0xD1B5, +0x01AC, +0x3000, +0x01AF, +0x0016, +0x0179, +0x0080, +0x0800, +0x0179, +0x01AD, +0x0080, +0xD9B6, +0x0807, +0x0313, +0x0C23, +0x864B, +0x0800, +0x0179, +0x3801, +0x0802, +0x003F, +0x0803, +0x00C0, +0x5461, +0xB31F, +0x5422, +0xB31F, +0x8329, +0x0C4E, +0x19BA, +0x33AE, +0xA329, +0x1B33, +0xA329, +0x0C4F, +0xD9BA, +0x33AF, +0x82EF, +0x0C2E, +0x1BF4, +0x33AE, +0xA34D, +0x0180, +0x01FF, +0x0181, +0x5555, +0x0182, +0x1400, +0xD183, +0x0184, +0x6C00, +0x0185, +0x2408, +0x0807, +0x033B, +0x8E5B, +0x01A8, +0x0140, +0xD1B5, +0x01AC, +0x3000, +0x01AF, +0x0018, +0x017A, +0x0080, +0x0800, +0x017A, +0x01AD, +0x0080, +0xD9B6, +0x0807, +0x034D, +0x0C23, +0x864B, +0x0800, +0x017A, +0x3801, +0x0802, +0x003F, +0x0803, +0x00C0, +0x5461, +0xB359, +0x5422, +0xB359, +0x8363, +0x0C4E, +0x19BA, +0x33AE, +0xA363, +0x1B33, +0xA363, +0x0C4F, +0xD9BA, +0x33AF, +0x82EF, +0x080E, +0x0400, +0x1B6F, +0x33AE, +0xA38D, +0x0C4E, +0x19BA, +0x33AE, +0xA38B, +0x0800, +0x009B, +0x1979, +0x31A1, +0x197A, +0x31A2, +0x5420, +0xB375, +0x8379, +0x5440, +0xB379, +0xDBF2, +0x838D, +0x5420, +0xB381, +0x5440, +0xB37E, +0x8381, +0x03F2, +0x0002, +0x838D, +0x5420, +0xB38D, +0x5440, +0xB38D, +0x03F2, +0x0003, +0x0C4F, +0xD9BA, +0x33AF, +0x82EF, +0x03F2, +0x0003, +0x1BF2, +0x5C6D, +0xA395, +0x03ED, +0x0025, +0x03EE, +0x0025, +0x8399, +0x03ED, +0x0037, +0x03EE, +0x0037, +0x1B32, +0xA3BB, +0x0180, +0x01FF, +0x0181, +0xAAAA, +0x0182, +0x2800, +0xD183, +0x0184, +0x7000, +0x0185, +0x2408, +0x0807, +0x03A9, +0x8D7D, +0x01A8, +0x0140, +0xD1B5, +0x01AC, +0x3000, +0x01AF, +0x0010, +0x0173, +0x0080, +0x0800, +0x0173, +0x01AD, +0x0080, +0xD9B6, +0x0807, +0x03BB, +0x0C23, +0x864B, +0x0800, +0x0173, +0x3801, +0x0802, +0x003F, +0x0803, +0x00C0, +0x5423, +0xB3C5, +0x83C7, +0x5441, +0xB3D1, +0x0C4E, +0x19BA, +0x33AE, +0xA3D1, +0x1B33, +0xA3D1, +0x0C4F, +0xD9BA, +0x33AF, +0x82EF, +0x1B32, +0xA3F3, +0x0180, +0x01FF, +0x0181, +0xAAAA, +0x0182, +0x2800, +0xD183, +0x0184, +0x7000, +0x0185, +0x2408, +0x0807, +0x03E1, +0x8DA1, +0x01A8, +0x0140, +0xD1B5, +0x01AC, +0x3000, +0x01AF, +0x0011, +0x0174, +0x0080, +0x0800, +0x0174, +0x01AD, +0x0080, +0xD9B6, +0x0807, +0x03F3, +0x0C23, +0x864B, +0x0800, +0x0174, +0x3801, +0x0802, +0x003F, +0x0803, +0x00C0, +0x5423, +0xB3FD, +0x83FF, +0x5441, +0xB409, +0x0C4E, +0x19BA, +0x33AE, +0xA409, +0x1B33, +0xA409, +0x0C4F, +0xD9BA, +0x33AF, +0x82EF, +0x1B32, +0xA42B, +0x0180, +0x01FF, +0x0181, +0x5555, +0x0182, +0x1400, +0xD183, +0x0184, +0x7000, +0x0185, +0x2408, +0x0807, +0x0419, +0x8E11, +0x01A8, +0x0140, +0xD1B5, +0x01AC, +0x3000, +0x01AF, +0x0012, +0x0175, +0x0080, +0x0800, +0x0175, +0x01AD, +0x0080, +0xD9B6, +0x0807, +0x042B, +0x0C23, +0x864B, +0x0800, +0x0175, +0x3801, +0x0802, +0x003F, +0x0803, +0x00C0, +0x5423, +0xB435, +0x8437, +0x5441, +0xB441, +0x0C4E, +0x19BA, +0x33AE, +0xA441, +0x1B33, +0xA441, +0x0C4F, +0xD9BA, +0x33AF, +0x82EF, +0x1B32, +0xA463, +0x0180, +0x01FF, +0x0181, +0x5555, +0x0182, +0x1400, +0xD183, +0x0184, +0x7000, +0x0185, +0x2408, +0x0807, +0x0451, +0x8E35, +0x01A8, +0x0140, +0xD1B5, +0x01AC, +0x3000, +0x01AF, +0x0013, +0x0176, +0x0080, +0x0800, +0x0176, +0x01AD, +0x0080, +0xD9B6, +0x0807, +0x0463, +0x0C23, +0x864B, +0x0800, +0x0176, +0x3801, +0x0802, +0x003F, +0x0803, +0x00C0, +0x5423, +0xB46D, +0x846F, +0x5441, +0xB479, +0x0C4E, +0x19BA, +0x33AE, +0xA479, +0x1B33, +0xA479, +0x0C4F, +0xD9BA, +0x33AF, +0x82EF, +0x0C8F, +0xD324, +0x33AF, +0x1B3D, +0xA49E, +0x0180, +0x01FF, +0x0181, +0xAAAA, +0x0182, +0x2800, +0xD183, +0x0184, +0x6800, +0x0185, +0x2408, +0x0807, +0x048C, +0x8DEC, +0x01A8, +0x0140, +0xD1B5, +0x01AC, +0x3000, +0x01AF, +0x0014, +0x0345, +0x0080, +0x0800, +0x0345, +0x01AD, +0x0080, +0xD9B6, +0x0807, +0x049E, +0x0C23, +0x864B, +0x1B3D, +0xA4C0, +0x0180, +0x01FF, +0x0181, +0x5555, +0x0182, +0x1400, +0xD183, +0x0184, +0x6800, +0x0185, +0x2408, +0x0807, +0x04AE, +0x8E80, +0x01A8, +0x0140, +0xD1B5, +0x01AC, +0x3000, +0x01AF, +0x0015, +0x0346, +0x0080, +0x0800, +0x0346, +0x01AD, +0x0080, +0xD9B6, +0x0807, +0x04C0, +0x0C23, +0x864B, +0x1B3E, +0xA4DD, +0x0800, +0x00FB, +0x1B45, +0x31A1, +0x1B46, +0x31A2, +0x5401, +0xB4D2, +0x5402, +0xB4D2, +0x0C80, +0x5420, +0xB4D2, +0x5440, +0xB4D2, +0x84DD, +0x0C2E, +0x19BA, +0x33AE, +0xA4DD, +0x0C8F, +0xDB24, +0x33AF, +0x0C2F, +0xD9BA, +0x33AF, +0x847C, +0x0C4E, +0x1BF4, +0x33AE, +0xA508, +0x0180, +0x01FF, +0x0181, +0xAAAA, +0x0182, +0x2800, +0xD183, +0x0184, +0x7000, +0x0185, +0x2408, +0x01A8, +0x0140, +0xD1B5, +0x01AC, +0x3000, +0x01AF, +0x0010, +0x0807, +0x04F6, +0x8EA5, +0x01A8, +0x0100, +0xD1B5, +0x01AC, +0x3000, +0x01AF, +0x0010, +0x034F, +0x0080, +0x0800, +0x034F, +0x01AD, +0x0080, +0xD9B6, +0x0807, +0x0508, +0x0C23, +0x864B, +0x1B4F, +0x080F, +0xFF00, +0x297F, +0x080F, +0xFFFF, +0x0C4E, +0x1BF4, +0x33AE, +0xA539, +0x0180, +0x01FF, +0x0181, +0x5555, +0x0182, +0x1400, +0xD183, +0x0184, +0x7000, +0x0185, +0x2408, +0x01A8, +0x0140, +0xD1B5, +0x01AC, +0x3000, +0x01AF, +0x0012, +0x0807, +0x0527, +0x8EC9, +0x01A8, +0x0100, +0xD1B5, +0x01AC, +0x3000, +0x01AF, +0x0012, +0x0350, +0x0080, +0x0800, +0x0350, +0x01AD, +0x0080, +0xD9B6, +0x0807, +0x0539, +0x0C23, +0x864B, +0x1B50, +0x080F, +0x00FF, +0x297F, +0x080F, +0xFFFF, +0x0C2E, +0x1B6F, +0x33AE, +0xA5CF, +0x0CEE, +0x1B0C, +0x33AE, +0x0800, +0x0080, +0x51A0, +0x080F, +0x07FF, +0x29B0, +0x33AF, +0xD9B7, +0x0800, +0x0080, +0x1BED, +0x51A0, +0x2969, +0x31A0, +0x01AF, +0x0016, +0x21AD, +0xD9B6, +0x0180, +0x03FF, +0xD981, +0xD182, +0xD183, +0x0184, +0x4000, +0x0185, +0x2408, +0x01A8, +0x0100, +0xD1B5, +0x01AC, +0x9346, +0x01AF, +0x001B, +0x03FC, +0x0080, +0x0800, +0x03FC, +0x01AD, +0x0080, +0xD9B6, +0x0807, +0x0573, +0x0C23, +0x864B, +0x01A8, +0x0100, +0xD1B5, +0x01AC, +0x90DA, +0x01AF, +0x0003, +0x03FD, +0x0080, +0x0800, +0x03FD, +0x01AD, +0x0080, +0xD9B6, +0x0807, +0x0585, +0x0C03, +0x864B, +0x0180, +0x01FF, +0x0181, +0xAAAA, +0x0182, +0x2800, +0xD183, +0x0184, +0x6C00, +0x0185, +0x2408, +0x0807, +0x0593, +0x8DC7, +0x01A8, +0x0140, +0xD1B5, +0x01AC, +0x3000, +0x01AF, +0x0016, +0x03ED, +0x0080, +0x0800, +0x03ED, +0x01AD, +0x0080, +0xD9B6, +0x0807, +0x05A5, +0x0C23, +0x864B, +0x0180, +0x01FF, +0x0181, +0x5555, +0x0182, +0x1400, +0xD183, +0x0184, +0x6C00, +0x0185, +0x2408, +0x0807, +0x05B3, +0x8E5B, +0x01A8, +0x0140, +0xD1B5, +0x01AC, +0x3000, +0x01AF, +0x0018, +0x03EE, +0x0080, +0x0800, +0x03EE, +0x01AD, +0x0080, +0xD9B6, +0x0807, +0x05C5, +0x0C23, +0x864B, +0x1BEE, +0x31A0, +0x1BED, +0x31A1, +0x197A, +0x55A0, +0x2BEE, +0x1979, +0x55A1, +0x2BED, +0x080E, +0x07F8, +0x1B0C, +0x33AE, +0x080F, +0x07F8, +0x29B0, +0x33AF, +0xD9B7, +0x080F, +0x0800, +0xD1B0, +0x33AF, +0xD9B7, +0x01A8, +0x0140, +0x1973, +0x29AD, +0x01AF, +0x0010, +0xD9B6, +0x1974, +0x29AD, +0x01AF, +0x0011, +0xD9B6, +0x1979, +0x29AD, +0x01AF, +0x0016, +0xD9B6, +0x1B45, +0x29AD, +0x01AF, +0x0014, +0xD9B6, +0x1975, +0x29AD, +0x01AF, +0x0012, +0xD9B6, +0x1976, +0x29AD, +0x01AF, +0x0013, +0xD9B6, +0x197A, +0x29AD, +0x01AF, +0x0018, +0xD9B6, +0x1B46, +0x29AD, +0x01AF, +0x0015, +0xD9B6, +0x1973, +0x2B4B, +0x1974, +0x2B4C, +0x1979, +0x2B51, +0x080F, +0xFF00, +0x2BEF, +0x080F, +0x00FF, +0x2BEF, +0x33AF, +0x1975, +0x2B4D, +0x1976, +0x2B4E, +0x197A, +0x2B52, +0x080F, +0xFF00, +0x2BF0, +0x080F, +0x00FF, +0x2BF0, +0x33AF, +0x01A8, +0x0100, +0x1B4F, +0x29AD, +0x01AF, +0x0010, +0xD9B6, +0x1B50, +0x29AD, +0x01AF, +0x0012, +0xD9B6, +0x1B41, +0x29AD, +0x01AF, +0x0002, +0xD9B6, +0x1B42, +0x29AD, +0x01AF, +0x0003, +0xD9B6, +0x33FE, +0x0C3F, +0x804B, +0xD1AC, +0x01B3, +0x0077, +0xD100, +0xD1A8, +0xD1AE, +0x8646, +0x33FE, +0x0C3F, +0x804D, +0xD1A8, +0xD9B6, +0x080F, +0x0400, +0xD185, +0x33AF, +0x9006, +0x0804, +0x0040, +0x5C03, +0xA650, +0x8653, +0x0CE1, +0x7080, +0x8655, +0x0CC1, +0x7080, +0x6660, +0x0C42, +0x5443, +0xB65B, +0x6260, +0x8678, +0xA669, +0x080E, +0x7FFF, +0x198A, +0x33AE, +0x31A2, +0x4022, +0x080E, +0x7FFF, +0x1986, +0x33AE, +0x426D, +0x55A2, +0x8678, +0x080E, +0x7FFF, +0x1986, +0x33AE, +0x31A2, +0x4022, +0x426D, +0x55A2, +0x31A2, +0x080E, +0x7FFF, +0x198A, +0x33AE, +0x402D, +0x544D, +0xB680, +0x0C02, +0x55A2, +0x31A5, +0x380D, +0x3802, +0x548D, +0x8686, +0x31A5, +0x3802, +0xA684, +0x8691, +0x380D, +0x508D, +0x35A0, +0x29AD, +0xD9B6, +0x5C03, +0xA68E, +0x0C37, +0x700F, +0x8693, +0x0C17, +0x700F, +0x8693, +0x31A5, +0x3802, +0x4224, +0x5C21, +0xA655, +0x0C81, +0x6660, +0x0C44, +0x5483, +0xB69D, +0x6260, +0x86BA, +0xA6AB, +0x080E, +0x7FFF, +0x198A, +0x33AE, +0x31A4, +0x4024, +0x080E, +0x7FFF, +0x1986, +0x33AE, +0x426D, +0x55A4, +0x86BA, +0x080E, +0x7FFF, +0x1986, +0x33AE, +0x31A4, +0x4024, +0x426D, +0x55A4, +0x31A4, +0x080E, +0x7FFF, +0x198A, +0x33AE, +0x402D, +0x548D, +0x31A4, +0xB6CD, +0x0C04, +0x55A4, +0x31A4, +0x54A4, +0xB6C3, +0x3085, +0x3802, +0x32ED, +0xA6C8, +0x380D, +0x5C2D, +0x86CA, +0x380D, +0x5C4D, +0x31A4, +0xB6DB, +0x86EF, +0x54A4, +0xB6D1, +0x3085, +0x3802, +0x32ED, +0xA6D6, +0x380D, +0x582D, +0x86D8, +0x380D, +0x584D, +0x31A4, +0x430D, +0xA6EF, +0x5C21, +0xA6E4, +0x3804, +0x5482, +0xA6E1, +0x86EF, +0x3440, +0x304D, +0x86E6, +0x3480, +0x308D, +0x29AD, +0xD9B6, +0x5C03, +0xA6EC, +0x700F, +0x86ED, +0x700F, +0x5C01, +0xA697, +0x33DF, +0x9007, +0x1B36, +0xA709, +0xD35E, +0x038D, +0x0030, +0xD10D, +0x010D, +0x0002, +0x0306, +0x000C, +0x0C2E, +0x1919, +0x33AE, +0xA700, +0x86FB, +0x0306, +0x0008, +0x0C2E, +0x1919, +0x33AE, +0xA702, +0x0305, +0x000C, +0xD10D, +0x038D, +0x0030, +0x1B38, +0xA711, +0x080F, +0x0080, +0xD37B, +0x33AF, +0xD38D, +0x1B38, +0xA716, +0x0C6C, +0x871E, +0x1B34, +0xA71D, +0x080E, +0x01E0, +0x131C, +0x33AE, +0x871E, +0x0C0C, +0x33FE, +0x0C3F, +0x8946, +0x1B49, +0x2B47, +0x038D, +0x0030, +0xD1A8, +0xD161, +0x0162, +0x0042, +0x0163, +0x0060, +0xD164, +0xD165, +0x0167, +0x21A2, +0x1BEE, +0x2BCD, +0x1BED, +0x2BCC, +0x13CD, +0x1B52, +0x518D, +0x31AC, +0x430D, +0xA73B, +0x318D, +0x873D, +0x080D, +0x00FF, +0x31A1, +0x080F, +0xFF00, +0x2969, +0x33AF, +0x13CC, +0x1B51, +0x518D, +0x31AC, +0x430D, +0xA74A, +0x318D, +0x874C, +0x080D, +0x00FF, +0x31A1, +0x080F, +0x00FF, +0x2969, +0x33AF, +0x0181, +0xFFFF, +0x0182, +0x3C02, +0x0183, +0x0800, +0x0184, +0x7060, +0x0185, +0x2402, +0x1B67, +0x2980, +0x1B68, +0x2960, +0x1B69, +0x2966, +0x1B6A, +0x2968, +0x1B36, +0xA76B, +0x0807, +0x076A, +0x33FE, +0x0C1F, +0x89C5, +0x6C00, +0xD162, +0x0163, +0x001F, +0x0182, +0x3C23, +0x0183, +0x0087, +0x0184, +0x7068, +0x0185, +0x247C, +0x1B6B, +0x2980, +0x1B6C, +0x2960, +0x1B6D, +0x2966, +0x1B6E, +0x2968, +0x1B36, +0xA781, +0x6C00, +0x0182, +0x3C02, +0x0183, +0x0800, +0x0184, +0x7060, +0x0185, +0x2402, +0x0162, +0x0042, +0x0163, +0x0060, +0x0167, +0x39C0, +0x1B7C, +0x2980, +0x1B7D, +0x2960, +0x1B7E, +0x2966, +0x1B7F, +0x2968, +0x1B36, +0xA7E0, +0x0807, +0x079E, +0x33FE, +0x0C1F, +0x89C5, +0x6C00, +0x080E, +0x4000, +0x1B6F, +0x33AE, +0xA7E0, +0x080E, +0x03C0, +0x196C, +0x33AE, +0x5CED, +0xB7E0, +0x0180, +0x01FF, +0x080F, +0x03E0, +0x0182, +0x0002, +0x33AF, +0x6620, +0xB7B4, +0x87E0, +0xA7B6, +0x87E0, +0x080F, +0x3FFF, +0xD160, +0x33AF, +0x080F, +0x0038, +0x0166, +0x0005, +0x33AF, +0x080E, +0x03C0, +0x196C, +0x33AE, +0x402D, +0x31A0, +0x080E, +0x003F, +0x196C, +0x33AE, +0xA7CC, +0x5820, +0x87CD, +0x5840, +0x31A0, +0x080F, +0x7C00, +0x2167, +0x080F, +0x03E0, +0x2167, +0x33AF, +0x1169, +0x3181, +0x080F, +0x1000, +0xD166, +0x33AF, +0x0169, +0xFFFF, +0x6C00, +0x302D, +0x2969, +0x1969, +0x2BF7, +0x080E, +0x0020, +0x1B6F, +0x33AE, +0xA7EA, +0x33FE, +0x0C3F, +0x8BA3, +0x080F, +0x7C00, +0xD3F6, +0x33AF, +0xD3F8, +0xD3F9, +0xD3FA, +0x080E, +0x8000, +0x1BF6, +0x33AE, +0xA891, +0x0CC0, +0x0D61, +0x0C22, +0x0C23, +0x0804, +0x00F5, +0x0807, +0x0801, +0x33FE, +0x0C3F, +0x89E6, +0x31B8, +0x080F, +0xFF00, +0x2BF8, +0x33AF, +0x0CC0, +0x0D61, +0x0C22, +0x0C23, +0x0804, +0x00F5, +0x0807, +0x0811, +0x33FE, +0x0C3F, +0x8A57, +0x31B9, +0x080F, +0x00FF, +0x2BF8, +0x33AF, +0x0C40, +0x0D61, +0x0C22, +0x0C23, +0x0804, +0x00F5, +0x0807, +0x0821, +0x33FE, +0x0C3F, +0x89E6, +0x31BA, +0x080F, +0xFF00, +0x2BF9, +0x33AF, +0x0C40, +0x0D61, +0x0C22, +0x0C23, +0x0804, +0x00F5, +0x0807, +0x0831, +0x33FE, +0x0C3F, +0x8A57, +0x31BB, +0x080F, +0x00FF, +0x2BF9, +0x33AF, +0x0807, +0x083B, +0x33FE, +0x0C3F, +0x8AC8, +0x080E, +0x0400, +0x1BF6, +0x33AE, +0xA841, +0x8891, +0x080E, +0x6000, +0x1BF6, +0x33AE, +0x5C2D, +0xA848, +0x8868, +0x0CC0, +0x0C61, +0x0D02, +0x0C03, +0x0804, +0x00FF, +0x0807, +0x0853, +0x33FE, +0x0C3F, +0x89E6, +0x31B8, +0x080F, +0xFF00, +0x2BFA, +0x33AF, +0x0C80, +0x0D61, +0x0D02, +0x0C03, +0x0C04, +0x0807, +0x0862, +0x33FE, +0x0C3F, +0x89E6, +0x31BA, +0x080F, +0x00FF, +0x2BFA, +0x33AF, +0x8887, +0x0CC0, +0x0C61, +0x0D02, +0x0C03, +0x0804, +0x00FF, +0x0807, +0x0873, +0x33FE, +0x0C3F, +0x8A57, +0x31B9, +0x080F, +0xFF00, +0x2BFA, +0x33AF, +0x0C80, +0x0D61, +0x0D02, +0x0C03, +0x0C04, +0x0807, +0x0882, +0x33FE, +0x0C3F, +0x8A57, +0x31BB, +0x080F, +0x00FF, +0x2BFA, +0x33AF, +0x0807, +0x088C, +0x33FE, +0x0C3F, +0x8B11, +0x0807, +0x0891, +0x33FE, +0x0C3F, +0x8B34, +0x080E, +0x0400, +0x1BF6, +0x33AE, +0xA8E9, +0x0181, +0xFFFF, +0x0182, +0x3C06, +0x0183, +0x0800, +0x0184, +0x7060, +0x0185, +0x247E, +0x0161, +0x0009, +0x0162, +0x00C2, +0x0163, +0x7F80, +0xD164, +0xD165, +0x0167, +0x21A2, +0x1BF7, +0x2969, +0x1BE0, +0x2980, +0x1BE1, +0x2960, +0x1BE2, +0x2966, +0x1BE3, +0x2968, +0x1B37, +0xA8E9, +0x0807, +0x08BB, +0x33FE, +0x0C1F, +0x89C5, +0x6C00, +0x080E, +0xFF00, +0x197B, +0x33AE, +0x31A1, +0x080E, +0x4000, +0x1963, +0x33AE, +0xA8C7, +0x88D0, +0x0807, +0x08CA, +0x8D52, +0x31A2, +0xA8CE, +0x5461, +0x88CF, +0x5061, +0x31A1, +0x1351, +0x302D, +0x558D, +0x2BCC, +0x080E, +0x00FF, +0x197B, +0x33AE, +0x31A1, +0x080E, +0x4000, +0x1963, +0x33AE, +0xA8DF, +0x88E5, +0x304D, +0xA8E3, +0x5461, +0x88E4, +0x5061, +0x31A1, +0x1352, +0x302D, +0x558D, +0x2BCD, +0x33FE, +0x0C3F, +0x86CB, +0x0182, +0x3C06, +0x0183, +0x0800, +0x0185, +0x247E, +0x0163, +0x7F80, +0x1BE4, +0x2980, +0x1BE5, +0x2960, +0x1BE6, +0x2966, +0x1BE7, +0x2968, +0x080E, +0x0400, +0x1BF6, +0x33AE, +0xA902, +0x891D, +0x080F, +0x0F80, +0x0163, +0x001E, +0x33AF, +0x080E, +0x0800, +0x1BF6, +0x33AE, +0xA912, +0x080E, +0x1000, +0x1BF6, +0x33AE, +0xA918, +0x891D, +0x080F, +0x03E0, +0x0182, +0x0002, +0x33AF, +0x891D, +0x080F, +0x03E0, +0x0182, +0x0006, +0x33AF, +0x1B37, +0xA962, +0x13CD, +0x410C, +0x1BCC, +0x518D, +0x31A1, +0x1352, +0x410C, +0x502C, +0x31A2, +0x1352, +0x410C, +0x502C, +0x31A2, +0x1351, +0x504C, +0x2969, +0x0807, +0x0934, +0x33FE, +0x0C1F, +0x89C5, +0x6C00, +0x080E, +0xFF00, +0x197B, +0x33AE, +0x31A1, +0x080E, +0x4000, +0x1963, +0x33AE, +0xA940, +0x8949, +0x0807, +0x0943, +0x8D52, +0x31A2, +0xA947, +0x5461, +0x8948, +0x5061, +0x31A1, +0x1351, +0x302D, +0x558D, +0x2BCC, +0x080E, +0x00FF, +0x197B, +0x33AE, +0x31A1, +0x080E, +0x4000, +0x1963, +0x33AE, +0xA958, +0x895E, +0x304D, +0xA95C, +0x5461, +0x895D, +0x5061, +0x31A1, +0x1352, +0x302D, +0x558D, +0x2BCD, +0x080E, +0x0020, +0x1B6F, +0x33AE, +0xA96A, +0x33FE, +0x0C3F, +0x8C25, +0x080E, +0x0020, +0x1B6F, +0x33AE, +0xA976, +0x33FE, +0x0C3F, +0x8D47, +0x2BCB, +0x13CB, +0x3180, +0x2311, +0x33FE, +0x0C3F, +0x80F0, +0x038D, +0x0030, +0xDB5E, +0x1B38, +0xA982, +0x080F, +0x0080, +0xDB7B, +0x33AF, +0xD10D, +0x010D, +0x0002, +0x0306, +0x000C, +0x0C2E, +0x1919, +0x33AE, +0xA98C, +0x8987, +0xD306, +0x0C2E, +0x1919, +0x33AE, +0xA98D, +0x0305, +0x000C, +0xD10D, +0x8998, +0x038D, +0x0030, +0xDB5E, +0xD38D, +0xDB10, +0x1B86, +0xA99D, +0x899A, +0xD310, +0xDB8C, +0x080F, +0x0400, +0xD185, +0x33AF, +0x9006, +0x038D, +0x0029, +0x1BC5, +0xA9A9, +0x89BE, +0x1B5E, +0xA9AC, +0x89BE, +0x0D0E, +0x1913, +0x33AE, +0xA9AC, +0x080E, +0x01FC, +0x1BF6, +0x33AE, +0x31B7, +0xAA12, +0x89BB, +0x0C2D, +0x55B7, +0x31B7, +0xAA1C, +0x0C4F, +0xDBF6, +0x33AF, +0x080F, +0x0400, +0xD185, +0x33AF, +0x8A77, +0x0167, +0x21A2, +0x1B33, +0xA9DD, +0x0C21, +0x0C42, +0x13F2, +0x542C, +0xA9D4, +0x0181, +0xAAAA, +0x080F, +0x3C00, +0x0182, +0x000A, +0x33AF, +0x89DD, +0x544C, +0xA9DD, +0x0181, +0x5555, +0x080F, +0x3C00, +0x0182, +0x0005, +0x33AF, +0x33DF, +0x9007, +0x038D, +0x0029, +0x1BC5, +0xA9E6, +0x1BC6, +0xA9E6, +0x8A09, +0x7FFF, +0x0D0E, +0x1913, +0x33AE, +0xA9E7, +0x1BC5, +0xA9EE, +0x89F1, +0x0806, +0x09F1, +0x8A0F, +0x1BC6, +0xA9F4, +0x8A09, +0x1BF1, +0x31BC, +0x2BCC, +0x430D, +0x2BCD, +0x0806, +0x0A03, +0x080E, +0x0020, +0x1BF3, +0x33AE, +0xAA03, +0x33FE, +0x0C3F, +0x82BD, +0x0806, +0x0A08, +0x1B30, +0xAA08, +0x8AB4, +0x8EED, +0xD38D, +0x080F, +0x0400, +0xD185, +0x33AF, +0x807A, +0x1B59, +0xAA12, +0x8A09, +0x0C2F, +0xDB75, +0x33AF, +0x0C6F, +0x010D, +0x0002, +0x33AF, +0xD3A6, +0x03A6, +0x000A, +0x0180, +0x7D00, +0xD981, +0xD182, +0xD183, +0xD184, +0x0185, +0x2408, +0x01AC, +0xA080, +0x01AF, +0x0002, +0x0800, +0x0341, +0x0C01, +0x0C62, +0xD9AE, +0x0807, +0x0A32, +0x1B3A, +0xAA32, +0x8A82, +0x01AC, +0xA0C0, +0x01AF, +0x0003, +0x0800, +0x0342, +0x0C01, +0x0C62, +0x0807, +0x0A3F, +0x1B3A, +0xAA3F, +0x8A82, +0x0C4E, +0x1BF6, +0x33AE, +0xAA45, +0x1B5E, +0xA9B7, +0x01AC, +0x2000, +0x0180, +0x7D00, +0x0181, +0x5555, +0x0182, +0x1446, +0x0183, +0x010D, +0x0184, +0x2800, +0x0185, +0x6410, +0xD1AC, +0x01AF, +0x0014, +0x0800, +0x0345, +0x0C21, +0x0C62, +0x0807, +0x0A5F, +0x1B39, +0xAA5F, +0x8A82, +0x0180, +0x7D00, +0x0181, +0xAAAA, +0x0182, +0x2846, +0x0183, +0x010D, +0x0184, +0x2800, +0x0185, +0x6410, +0xD1AC, +0x01AF, +0x0015, +0x0800, +0x0346, +0x0C21, +0x0C62, +0x0807, +0x0A77, +0x1B39, +0xAA77, +0x8A82, +0xD1AE, +0xD1AC, +0xD3A6, +0x7000, +0x0C6F, +0xD10D, +0x33AF, +0x0C2F, +0xD375, +0x33AF, +0x9006, +0x380D, +0x29AD, +0xD9B6, +0x7080, +0x667C, +0x302D, +0xAA8F, +0x080E, +0x7FFF, +0x198A, +0x1186, +0x33AE, +0x8A94, +0x080E, +0x7FFF, +0x198B, +0x1186, +0x33AE, +0x402D, +0x31A3, +0x3184, +0x3185, +0x304D, +0xAA9B, +0x8A9E, +0x4225, +0x5C22, +0x8A98, +0x5085, +0x546D, +0xBAA2, +0x8AAB, +0x54A4, +0x55A3, +0xBAA6, +0x8AA7, +0x9007, +0x5E20, +0xBAB0, +0x3580, +0x9007, +0x5A20, +0x31A2, +0x430D, +0xAAA9, +0x304D, +0x29AD, +0xD9B6, +0x700F, +0x9007, +0x1B5E, +0xAAB7, +0x8A09, +0x080E, +0x8000, +0x1BEB, +0x33AE, +0xAB44, +0x0180, +0x7D00, +0x0181, +0xFFFF, +0x0182, +0x3C23, +0x0183, +0x0087, +0x0184, +0x3068, +0x0185, +0x647C, +0xD160, +0xD161, +0xD162, +0x0163, +0x001F, +0x0164, +0x000A, +0xD165, +0x0166, +0x7800, +0x0167, +0x21A2, +0xD168, +0x0169, +0xB7B7, +0x0D0C, +0x080E, +0x03E0, +0x196D, +0x33AE, +0x55AC, +0xAB42, +0x0180, +0x1964, +0x6620, +0x0C00, +0x0C01, +0x080E, +0x7FFF, +0x1186, +0x33AE, +0x080D, +0x0100, +0x518D, +0x31AC, +0x0C2E, +0x1963, +0x33AE, +0xAAF0, +0x8AF8, +0x080E, +0x7FFF, +0x1989, +0x33AE, +0x500D, +0x31A0, +0x5181, +0x31A1, +0x0C4E, +0x1963, +0x33AE, +0xAAFD, +0x8B05, +0x080E, +0x7FFF, +0x198A, +0x33AE, +0x500D, +0x31A0, +0x5181, +0x31A1, +0x0C8E, +0x1963, +0x33AE, +0xAB0A, +0x8B12, +0x080E, +0x7FFF, +0x198B, +0x33AE, +0x500D, +0x31A0, +0x5181, +0x31A1, +0x0D0E, +0x1963, +0x33AE, +0xAB17, +0x8B1F, +0x080E, +0x7FFF, +0x198C, +0x33AE, +0x500D, +0x31A0, +0x5181, +0x31A1, +0x0E0E, +0x1963, +0x33AE, +0xAB24, +0x8B2C, +0x080E, +0x7FFF, +0x198D, +0x33AE, +0x500D, +0x31A0, +0x5181, +0x31A1, +0x422D, +0x540D, +0xBB44, +0x080F, +0x03FF, +0x0182, +0x0084, +0x33AF, +0x0C2F, +0xD183, +0x33AF, +0x080F, +0x0020, +0xD184, +0x33AF, +0x0FEF, +0xD963, +0x33AF, +0x0180, +0x7D00, +0x6C00, +0x8B44, +0xBB44, +0x6C00, +0x13EE, +0x319A, +0x410C, +0x1BED, +0x31BB, +0x518D, +0x31BC, +0x1B3C, +0xAC2C, +0x0180, +0x07FF, +0x0181, +0xFFFF, +0x0182, +0x3C06, +0x0183, +0x0800, +0x0184, +0x3060, +0x0185, +0x6402, +0x0160, +0x0C07, +0xD161, +0x0162, +0x0042, +0x0163, +0x3000, +0xD164, +0xD165, +0x0166, +0x7828, +0x0167, +0x21A2, +0xD168, +0x0807, +0x0B6C, +0x33FE, +0x0C1F, +0x89C5, +0x0FEF, +0x0182, +0x0002, +0x33AF, +0x1352, +0x1BEE, +0x518D, +0x31AC, +0x430D, +0xAB78, +0x318D, +0x8B7A, +0x080D, +0x00FF, +0x31A1, +0x080F, +0xFF00, +0x2969, +0x33AF, +0x1351, +0x1BED, +0x518D, +0x31AC, +0x430D, +0xAB87, +0x318D, +0x8B89, +0x080D, +0x00FF, +0x31A1, +0x080F, +0x00FF, +0x2969, +0x33AF, +0x6C00, +0x1351, +0x080E, +0xFF00, +0x197B, +0x33AE, +0x558D, +0xBB98, +0x0C1B, +0x8B99, +0x31BB, +0x1352, +0x080E, +0x00FF, +0x197B, +0x33AE, +0x558D, +0xBBA2, +0x0C1A, +0x8BA3, +0x31BA, +0x0180, +0x7D00, +0x0181, +0xFFFF, +0x0182, +0x3C02, +0x0183, +0x0800, +0x0184, +0x3060, +0x0185, +0x6402, +0xD160, +0xD161, +0x0162, +0x0042, +0x0163, +0x0060, +0x0164, +0x00D0, +0xD165, +0x0166, +0x7800, +0x0167, +0x21A2, +0xD168, +0x13CD, +0x1B52, +0x518D, +0x31AC, +0x430D, +0xABC5, +0x318D, +0x8BC7, +0x080D, +0x00FF, +0x31A1, +0x080F, +0xFF00, +0x2969, +0x33AF, +0x13CC, +0x1B51, +0x518D, +0x31AC, +0x430D, +0xABD4, +0x318D, +0x8BD6, +0x080D, +0x00FF, +0x31A1, +0x080F, +0x00FF, +0x2969, +0x33AF, +0x0807, +0x0BE0, +0x33FE, +0x0C1F, +0x89C5, +0xD160, +0x080F, +0x0038, +0x0166, +0x0005, +0x080F, +0x1000, +0xD166, +0x080F, +0x0E00, +0x0166, +0x0004, +0x33AF, +0x1BED, +0x31A2, +0x545B, +0xBC0E, +0x080E, +0x03C0, +0x196C, +0x33AE, +0x402D, +0x31A0, +0x080E, +0x003F, +0x196C, +0x33AE, +0xABFE, +0x5820, +0x8BFF, +0x5840, +0x31A0, +0x0DC4, +0x5404, +0xBC04, +0x0DC0, +0x080F, +0x7C00, +0x2167, +0x080F, +0x03E0, +0x2167, +0x33AF, +0x0169, +0xFFFF, +0x8C2B, +0x1BED, +0x590D, +0x576D, +0xBC2C, +0x080E, +0x03C0, +0x196C, +0x33AE, +0x402D, +0x31A0, +0x080E, +0x003F, +0x196C, +0x33AE, +0xAC21, +0x5C20, +0xBC20, +0x0C0D, +0x31A0, +0x080F, +0x7C00, +0x2167, +0x080F, +0x03E0, +0x2167, +0x0FEF, +0x2167, +0x33AF, +0xD169, +0x6C00, +0x1B3B, +0xAC7E, +0x0180, +0x07FF, +0x0181, +0xFFFF, +0x0182, +0x3C06, +0x0183, +0x0800, +0x0184, +0x3060, +0x0185, +0x6402, +0x0160, +0x0C07, +0xD161, +0x0162, +0x0042, +0x0163, +0x3000, +0xD164, +0xD165, +0x0166, +0x7828, +0x0167, +0x21A2, +0xD168, +0x1352, +0x519A, +0x31AC, +0x430D, +0xAC4F, +0x318D, +0x8C51, +0x080D, +0x00FF, +0x31A1, +0x080F, +0xFF00, +0x2969, +0x33AF, +0x1351, +0x519B, +0x31AC, +0x430D, +0xAC5D, +0x318D, +0x8C5F, +0x080D, +0x00FF, +0x31A1, +0x080F, +0x00FF, +0x2969, +0x33AF, +0x0807, +0x0C69, +0x33FE, +0x0C1F, +0x89C5, +0x6C00, +0x1351, +0x080E, +0xFF00, +0x197B, +0x33AE, +0x558D, +0xBC73, +0x0C1B, +0x8C74, +0x31BB, +0x1352, +0x080E, +0x00FF, +0x197B, +0x33AE, +0x558D, +0xBC7D, +0x0C1A, +0x8C7E, +0x31BA, +0x080E, +0x0040, +0x1BF3, +0x33AE, +0xACB2, +0x0180, +0x7D00, +0x0181, +0xFFFF, +0x0182, +0x3C06, +0x0183, +0x0800, +0x0184, +0x3060, +0x0185, +0x647C, +0xD160, +0x0161, +0x0009, +0x0162, +0x0042, +0x0163, +0x0F00, +0x0164, +0xA000, +0x0165, +0x0999, +0x0166, +0x7800, +0x0167, +0x21A2, +0xD168, +0x334C, +0x410C, +0x336D, +0x518D, +0x31BC, +0x1352, +0x410C, +0x3381, +0x502C, +0x31A2, +0x1351, +0x504C, +0x2969, +0x0807, +0x0CB1, +0x33FE, +0x0C1F, +0x89C5, +0x6C00, +0x196B, +0x2B5A, +0x196D, +0x2B5C, +0x196C, +0x2B5B, +0x196E, +0x2B5D, +0x196F, +0x2B60, +0x1970, +0x2B61, +0x1971, +0x2B62, +0x1972, +0x2B63, +0x8CC3, +0x33FE, +0x0C3F, +0x8000, +0x9006, +0x080E, +0x3000, +0x1913, +0x080E, +0xFFFF, +0xACCE, +0x9006, +0x19B3, +0x0800, +0x0077, +0x540D, +0xACD4, +0x8D51, +0xD9AE, +0x01AF, +0x0010, +0x0800, +0x0348, +0x0801, +0x0347, +0x0802, +0x034B, +0x3C40, +0x0807, +0x0CE1, +0x8D52, +0x0807, +0x0CE5, +0x0C04, +0x8D64, +0x01AF, +0x0012, +0x0800, +0x0348, +0x0801, +0x0348, +0x0802, +0x034D, +0x3C40, +0x0807, +0x0CF1, +0x8D52, +0x0807, +0x0CF5, +0x0C04, +0x8D64, +0x01AF, +0x0011, +0x0800, +0x0348, +0x0801, +0x0347, +0x0802, +0x034C, +0x3C40, +0x0807, +0x0D01, +0x8D52, +0x0807, +0x0D05, +0x0C24, +0x8D64, +0x01AF, +0x0013, +0x0800, +0x0348, +0x0801, +0x0348, +0x0802, +0x034E, +0x3C40, +0x0807, +0x0D11, +0x8D52, +0x0807, +0x0D15, +0x0C24, +0x8D64, +0x19B3, +0x31A4, +0x0805, +0x01EE, +0x54A4, +0xAD1C, +0x8D3F, +0x0805, +0x01CC, +0x54A4, +0xAD21, +0x8D41, +0x0805, +0x0144, +0x54A4, +0xAD26, +0x8D43, +0x0805, +0x0188, +0x54A4, +0xAD2B, +0x8D46, +0x0805, +0x0100, +0x54A4, +0xAD30, +0x8D48, +0x0805, +0x0111, +0x54A4, +0xAD35, +0x8D4A, +0x0805, +0x0155, +0x54A4, +0xAD3A, +0x8D4C, +0x0805, +0x0177, +0x54A4, +0xAD4E, +0x8D4E, +0x01B3, +0x01CC, +0x01B3, +0x0144, +0x01B3, +0x0155, +0x8D4C, +0x01B3, +0x0100, +0x01B3, +0x0111, +0x01B3, +0x0155, +0x01B3, +0x0177, +0x01B3, +0x0077, +0xD1AE, +0x9006, +0x080E, +0x1FE0, +0x196E, +0x33AE, +0x31A3, +0x080E, +0x1000, +0x196E, +0x33AE, +0x31A4, +0xAD5E, +0x8D62, +0x080D, +0x0100, +0x546D, +0x31A3, +0x308D, +0x9007, +0xAD68, +0x308D, +0xAD72, +0x8D6B, +0x308D, +0xAD6B, +0x8D72, +0x3805, +0x5065, +0x31A4, +0x430D, +0xAD79, +0x308D, +0x8D76, +0x3805, +0x5465, +0xBD76, +0x8D79, +0x3C02, +0x35A1, +0x8D7A, +0x384D, +0x29AD, +0xD9B6, +0x9007, +0x01AF, +0x0010, +0x01AD, +0x0080, +0xD9B6, +0x01AF, +0x0011, +0xD1AD, +0xD9B6, +0x01AF, +0x0016, +0x01AD, +0x00FF, +0xD9B6, +0x01AF, +0x0014, +0xD1AD, +0xD9B6, +0x01AF, +0x0012, +0xD1AD, +0xD9B6, +0x01AF, +0x0013, +0xD1AD, +0xD9B6, +0x01AF, +0x0018, +0x01AD, +0x00FF, +0xD9B6, +0x01AF, +0x0015, +0xD1AD, +0xD9B6, +0x9007, +0x01AF, +0x0010, +0xD1AD, +0xD9B6, +0x01AF, +0x0011, +0x01AD, +0x0080, +0xD9B6, +0x01AF, +0x0016, +0x01AD, +0x00FF, +0xD9B6, +0x01AF, +0x0014, +0xD1AD, +0xD9B6, +0x01AF, +0x0012, +0x01AD, +0x00FF, +0xD9B6, +0x01AF, +0x0013, +0x01AD, +0x00FF, +0xD9B6, +0x01AF, +0x0018, +0x01AD, +0x00FF, +0xD9B6, +0x01AF, +0x0015, +0xD1AD, +0xD9B6, +0x9007, +0x01AF, +0x0010, +0xD1AD, +0xD9B6, +0x01AF, +0x0011, +0x01AD, +0x00FF, +0xD9B6, +0x01AF, +0x0016, +0x01AD, +0x0080, +0xD9B6, +0x01AF, +0x0014, +0xD1AD, +0xD9B6, +0x01AF, +0x0012, +0xD1AD, +0xD9B6, +0x01AF, +0x0013, +0x01AD, +0x00FF, +0xD9B6, +0x01AF, +0x0018, +0x01AD, +0x00FF, +0xD9B6, +0x01AF, +0x0015, +0xD1AD, +0xD9B6, +0x9007, +0x01AF, +0x0010, +0xD1AD, +0xD9B6, +0x01AF, +0x0011, +0x01AD, +0x00FF, +0xD9B6, +0x01AF, +0x0016, +0x01AD, +0x00FF, +0xD9B6, +0x01AF, +0x0014, +0x01AD, +0x0080, +0xD9B6, +0x01AF, +0x0012, +0xD1AD, +0xD9B6, +0x01AF, +0x0013, +0xD1AD, +0xD9B6, +0x01AF, +0x0018, +0x01AD, +0x00FF, +0xD9B6, +0x01AF, +0x0015, +0xD1AD, +0xD9B6, +0x9007, +0x01AF, +0x0010, +0xD1AD, +0xD9B6, +0x01AF, +0x0011, +0xD1AD, +0xD9B6, +0x01AF, +0x0016, +0x01AD, +0x00FF, +0xD9B6, +0x01AF, +0x0014, +0xD1AD, +0xD9B6, +0x01AF, +0x0012, +0x01AD, +0x0080, +0xD9B6, +0x01AF, +0x0013, +0xD1AD, +0xD9B6, +0x01AF, +0x0018, +0x01AD, +0x00FF, +0xD9B6, +0x01AF, +0x0015, +0xD1AD, +0xD9B6, +0x9007, +0x01AF, +0x0010, +0x01AD, +0x00FF, +0xD9B6, +0x01AF, +0x0011, +0x01AD, +0x00FF, +0xD9B6, +0x01AF, +0x0016, +0x01AD, +0x00FF, +0xD9B6, +0x01AF, +0x0014, +0xD1AD, +0xD9B6, +0x01AF, +0x0012, +0xD1AD, +0xD9B6, +0x01AF, +0x0013, +0x01AD, +0x0080, +0xD9B6, +0x01AF, +0x0018, +0x01AD, +0x00FF, +0xD9B6, +0x01AF, +0x0015, +0xD1AD, +0xD9B6, +0x9007, +0x01AF, +0x0010, +0xD1AD, +0xD9B6, +0x01AF, +0x0011, +0x01AD, +0x00FF, +0xD9B6, +0x01AF, +0x0016, +0x01AD, +0x00FF, +0xD9B6, +0x01AF, +0x0014, +0xD1AD, +0xD9B6, +0x01AF, +0x0012, +0xD1AD, +0xD9B6, +0x01AF, +0x0013, +0x01AD, +0x00FF, +0xD9B6, +0x01AF, +0x0018, +0x01AD, +0x0080, +0xD9B6, +0x01AF, +0x0015, +0xD1AD, +0xD9B6, +0x9007, +0x01AF, +0x0010, +0xD1AD, +0xD9B6, +0x01AF, +0x0011, +0xD1AD, +0xD9B6, +0x01AF, +0x0016, +0x01AD, +0x00FF, +0xD9B6, +0x01AF, +0x0014, +0xD1AD, +0xD9B6, +0x01AF, +0x0012, +0xD1AD, +0xD9B6, +0x01AF, +0x0013, +0x01AD, +0x00FF, +0xD9B6, +0x01AF, +0x0018, +0x01AD, +0x00FF, +0xD9B6, +0x01AF, +0x0015, +0x01AD, +0x0080, +0xD9B6, +0x9007, +0x01AF, +0x0010, +0x01AD, +0x0080, +0xD9B6, +0x01AF, +0x0011, +0xD1AD, +0xD9B6, +0x01AF, +0x0016, +0x01AD, +0x00FF, +0xD9B6, +0x01AF, +0x0014, +0xD1AD, +0xD9B6, +0x01AF, +0x0012, +0xD1AD, +0xD9B6, +0x01AF, +0x0013, +0xD1AD, +0xD9B6, +0x01AF, +0x0018, +0x01AD, +0x00FF, +0xD9B6, +0x01AF, +0x0015, +0xD1AD, +0xD9B6, +0x9007, +0x01AF, +0x0010, +0xD1AD, +0xD9B6, +0x01AF, +0x0011, +0xD1AD, +0xD9B6, +0x01AF, +0x0016, +0x01AD, +0x00FF, +0xD9B6, +0x01AF, +0x0014, +0xD1AD, +0xD9B6, +0x01AF, +0x0012, +0x01AD, +0x0080, +0xD9B6, +0x01AF, +0x0013, +0xD1AD, +0xD9B6, +0x01AF, +0x0018, +0x01AD, +0x00FF, +0xD9B6, +0x01AF, +0x0015, +0xD1AD, +0xD9B6, +0x9007, +0x0C4E, +0x1B24, +0x33AE, +0xAEF2, +0x8F27, +0x038D, +0x0029, +0x0C2F, +0xDB75, +0x33AF, +0x0C6F, +0x010D, +0x0002, +0x33AF, +0xD3A6, +0x03A6, +0x000A, +0x0C2E, +0x1B24, +0x33AE, +0xAF10, +0xD9AE, +0x01AF, +0x0016, +0xD1AD, +0xD9B6, +0x01AF, +0x0018, +0x01AD, +0x00FF, +0xD9B6, +0x0C2F, +0xDB24, +0x33AF, +0x8F1D, +0xD9AE, +0x01AF, +0x0016, +0x01AD, +0x00FF, +0xD9B6, +0x01AF, +0x0018, +0xD1AD, +0xD9B6, +0x0C2F, +0xD324, +0x33AF, +0xD1AE, +0xD3A6, +0x7000, +0x0C6F, +0xD10D, +0x33AF, +0x0C2F, +0xD375, +0x33AF, +0xD38D, +0x8A09, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0180, +0x7D00, +0x0181, +0xAAAA, +0x0182, +0x2802, +0x0183, +0x0800, +0x0184, +0x3060, +0x0185, +0x6402, +0x0160, +0x0C1F, +0xD161, +0x0162, +0x0042, +0x0163, +0x3000, +0xD164, +0x0165, +0x3000, +0x0166, +0x7828, +0x0167, +0x21A2, +0xD168, +0x0169, +0xB7B7, +0x6E00, +0x197B, +0x430D, +0x31BA, +0x0180, +0x7D00, +0x0181, +0xAAAA, +0x0182, +0x2802, +0x0183, +0x0800, +0x0184, +0x3060, +0x0185, +0x6402, +0x0160, +0x0C1F, +0xD161, +0xD162, +0x0163, +0x3000, +0xD164, +0x0165, +0xB000, +0x0166, +0x7828, +0x0167, +0x21A2, +0xD168, +0x0169, +0x4949, +0x6E00, +0x197B, +0x430D, +0x55BA, +0xB043, +0x0C0D, +0x080F, +0x00FF, +0x2BE9, +0x33AE, +0x8D47, +0x2BCA, +0x33DF, +0x8CC6, +0x01A8, +0x0140, +0xD9B5, +0x01AC, +0xA200, +0x0180, +0x03FF, +0xD981, +0xD182, +0xD183, +0x0184, +0x4000, +0x0185, +0x2408, +0x0800, +0x0349, +0x0802, +0x034A, +0x0803, +0x01B4, +0x080E, +0x01E0, +0x1B1C, +0x33AE, +0x31A4, +0x0EED, +0x35A0, +0x3C43, +0xD9B8, +0x0816, +0x006B, +0x8071, +0xD1B5, +0x33DF, +0x1B27, +0xA070, +0x863A, +0x8644, +0x7080, +0x1B27, +0xA084, +0x1B35, +0xA084, +0x0801, +0x0022, +0x3805, +0x0DCD, +0x54AD, +0xA07D, +0x8081, +0x5E20, +0x3C43, +0xD9B8, +0x8078, +0x6670, +0xB084, +0x80AF, +0x380D, +0x2B53, +0x1B34, +0xA0AE, +0x308D, +0xA08B, +0x80AE, +0x3805, +0x0CED, +0x54AD, +0xA090, +0x80A3, +0x0DED, +0x54AD, +0xA094, +0x80A3, +0x0EED, +0x54AD, +0xA098, +0x80A3, +0x0FED, +0x54AD, +0xA09C, +0x80A3, +0x080D, +0x0027, +0x54AD, +0xA0A1, +0x80A3, +0x5C24, +0x31A4, +0x5A20, +0x3805, +0x0818, +0x002F, +0x54B8, +0xB0AB, +0x5E20, +0x80AE, +0x3C43, +0xD9B8, +0x8088, +0x9016, +0x5A20, +0x55A1, +0xB0B6, +0x3580, +0x318D, +0x2B53, +0x8084, +0x3C43, +0xD9B8, +0x700F, +0x8081, +0x0800, +0x0349, +0x0802, +0x034A, +0x0803, +0x01B4, +0x302D, +0xA0C4, +0x13C9, +0x80C5, +0x308C, +0x80CB, +0x3C43, +0xD9B8, +0xD1B5, +0x33DF, +0x9007, +0x3804, +0x5584, +0xB0E0, +0x548C, +0x31A4, +0x0801, +0x002F, +0x308D, +0xA0D5, +0x80DF, +0x5C24, +0x31A4, +0x5A20, +0x3805, +0x54A1, +0xB0DC, +0x80DF, +0x3C43, +0xD9B8, +0x80D2, +0x80C6, +0x31A4, +0x0C01, +0x308D, +0xA0E5, +0x80EF, +0x5C24, +0x31A4, +0x5E20, +0x3805, +0x5425, +0xB0EC, +0x80EF, +0x3C43, +0xD9B8, +0x80E2, +0x80C6, +0x0E0E, +0x1B6F, +0x33AE, +0xA275, +0x0180, +0x03FF, +0x0181, +0xFFFF, +0x0182, +0x3C46, +0xD183, +0x0184, +0x7020, +0x0185, +0x2404, +0x0160, +0x0C10, +0x0161, +0x0009, +0x0162, +0x00C2, +0xD163, +0xD164, +0xD165, +0x0166, +0x792B, +0x0167, +0x21A2, +0x0168, +0x4925, +0xD169, +0x1B33, +0xA127, +0x0C21, +0x0C42, +0x13F2, +0x542C, +0xA11E, +0x0181, +0xAAAA, +0x080F, +0x3C00, +0x0182, +0x000A, +0x33AF, +0x8127, +0x544C, +0xA127, +0x0181, +0x5555, +0x080F, +0x3C00, +0x0182, +0x0005, +0x33AF, +0x080E, +0x8000, +0x1963, +0x33AE, +0xA131, +0x080E, +0x0FE0, +0x116E, +0x33AE, +0x8135, +0x080E, +0x0FC0, +0x116E, +0x33AE, +0x3184, +0x080E, +0x1000, +0x116E, +0x33AE, +0x3185, +0x13CC, +0x3181, +0x1351, +0x502C, +0x31AC, +0x0C23, +0x5465, +0xB148, +0x548C, +0x31A2, +0xB15C, +0x0C02, +0x815C, +0x080E, +0x8000, +0x1963, +0x33AE, +0xA150, +0x0803, +0x0080, +0x8152, +0x0803, +0x0040, +0x548C, +0x506D, +0x31A2, +0x0803, +0x0100, +0x546D, +0xB15A, +0x815C, +0x0802, +0x00FF, +0x0C2F, +0xDB75, +0x33AF, +0x0C6F, +0x010D, +0x0002, +0x33AF, +0xD3A6, +0x03A6, +0x000A, +0x4102, +0x4302, +0x304D, +0xD9AE, +0x29AD, +0x01AF, +0x0016, +0xD9B6, +0x13CD, +0x3181, +0x1352, +0x502C, +0x31AC, +0x0C23, +0x5465, +0xB17B, +0x548C, +0x31A2, +0xB18F, +0x0C02, +0x818F, +0x080E, +0x8000, +0x1963, +0x33AE, +0xA183, +0x0803, +0x0080, +0x8185, +0x0803, +0x0040, +0x548C, +0x506D, +0x31A2, +0x0803, +0x0100, +0x546D, +0xB18D, +0x818F, +0x0802, +0x00FF, +0x4102, +0x4302, +0x304D, +0x29AD, +0x01AF, +0x0018, +0xD9B6, +0xD1AE, +0xD3A6, +0x7000, +0x0C6F, +0xD10D, +0x33AF, +0x0C2F, +0xD375, +0x33AF, +0x6647, +0x080E, +0x7FFF, +0x1989, +0x33AE, +0x402D, +0x31A3, +0x080E, +0x7FFF, +0x1986, +0x31A2, +0x31A4, +0x31AC, +0x080E, +0x01E0, +0x1B76, +0x33AE, +0xA1B2, +0x81B5, +0x422C, +0x5C2D, +0x81B0, +0x3181, +0x4282, +0x0C05, +0x0DEE, +0x1B76, +0x33AE, +0x31B7, +0xA1BE, +0x81C3, +0x5045, +0x31A5, +0x5C37, +0x31B7, +0x81BC, +0x0E0E, +0x1B76, +0x33AE, +0xA1CA, +0x50A4, +0x31A2, +0x81CC, +0x54A4, +0x31A2, +0x5022, +0x546D, +0xB1D0, +0x81D6, +0x5422, +0xB1D3, +0x81DB, +0x55A3, +0xB1DB, +0x81D8, +0xDB12, +0x81DC, +0x0312, +0x0002, +0x81DC, +0xD312, +0x080E, +0x0038, +0x1B77, +0x33AE, +0x31AC, +0x0CEE, +0x1B77, +0x33AE, +0x31A0, +0x080E, +0x00F0, +0x1B78, +0x33AE, +0x31A1, +0x0DEE, +0x1B78, +0x33AE, +0x31A2, +0x080E, +0x00E0, +0x196B, +0x33AE, +0x31A3, +0x080E, +0x03C0, +0x196C, +0x33AE, +0x31A4, +0x4024, +0x080E, +0x003F, +0x196C, +0x33AE, +0xA1FF, +0x8201, +0x5824, +0x31A4, +0x546C, +0xB206, +0x5444, +0xB206, +0x820B, +0x5403, +0xB210, +0x5481, +0xB210, +0x820E, +0x0313, +0x0002, +0x8211, +0xDB13, +0x8211, +0xD313, +0x080E, +0x03E0, +0x1379, +0x33AE, +0x3180, +0x0FEE, +0x1379, +0x33AE, +0x3181, +0x080E, +0x7F00, +0x137A, +0x33AE, +0x3184, +0x080E, +0x8000, +0x137A, +0x33AE, +0x3197, +0x080E, +0x007F, +0x137A, +0x33AE, +0x3185, +0x080E, +0x0080, +0x137A, +0x33AE, +0x3198, +0x080E, +0x03E0, +0x116D, +0x33AE, +0x3182, +0x0807, +0x0236, +0x82AB, +0x5440, +0xB239, +0x8272, +0x332D, +0xA241, +0x32ED, +0xA240, +0x5464, +0xB247, +0x8272, +0x8272, +0x32ED, +0xA244, +0x8247, +0x5483, +0xB247, +0x8272, +0x5422, +0xB24A, +0x826F, +0x332D, +0xA251, +0x330D, +0xA257, +0x54A3, +0xB257, +0x826F, +0x330D, +0xA254, +0x826F, +0x5465, +0xB257, +0x826F, +0x080E, +0x03C0, +0x196C, +0x33AE, +0x5CED, +0xA274, +0x1BED, +0x5C8D, +0x31AC, +0x1BCC, +0x55AC, +0xA264, +0x8266, +0xB26F, +0x8266, +0x1BEE, +0x5C8D, +0x31AC, +0x1BCD, +0x55AC, +0xA26D, +0x8274, +0xB26F, +0x8274, +0x0314, +0x0002, +0x8275, +0xDB14, +0x8275, +0xD314, +0x0C2F, +0xDB75, +0x33AF, +0x0C6F, +0x010D, +0x0002, +0x33AF, +0xD3A6, +0x03A6, +0x000A, +0x1B51, +0x1352, +0x3180, +0xD9AE, +0x29AD, +0x01AF, +0x0016, +0xD9B6, +0x21AD, +0x01AF, +0x0018, +0xD9B6, +0xD1AE, +0xD3A6, +0x7000, +0x0C6F, +0xD10D, +0x33AF, +0x0C2F, +0xD375, +0x33AF, +0x196B, +0x2B5A, +0x196D, +0x2B5C, +0x196C, +0x2B5B, +0x196E, +0x2B5D, +0x196F, +0x2B60, +0x1970, +0x2B61, +0x1971, +0x2B62, +0x1972, +0x2B63, +0x13CD, +0x410C, +0x1BCC, +0x518D, +0x2BF1, +0x33DF, +0x8979, +0x080E, +0x1FE0, +0x196E, +0x33AE, +0x31A3, +0x080E, +0x1000, +0x196E, +0x33AE, +0x31B9, +0xA2B7, +0x82BB, +0x080D, +0x0100, +0x546D, +0x31A3, +0x332D, +0x9007, +0x0C2F, +0xDB75, +0x33AF, +0x0C6F, +0x010D, +0x0002, +0x33AF, +0xD3A6, +0x03A6, +0x000A, +0x01B3, +0x0177, +0xD9AE, +0x82FB, +0x01B3, +0x0155, +0x01B3, +0x0144, +0x01B3, +0x01CC, +0x01B3, +0x01EE, +0x83DA, +0x01B3, +0x01CC, +0x01B3, +0x0144, +0x01B3, +0x0155, +0x01B3, +0x0177, +0x84AB, +0x01B3, +0x0155, +0x01B3, +0x0111, +0x01B3, +0x0100, +0x01B3, +0x0188, +0x859D, +0x01B3, +0x0100, +0x01B3, +0x0111, +0x01B3, +0x0155, +0x01B3, +0x0177, +0x01B3, +0x0077, +0xD1AE, +0xD3A6, +0x7000, +0x0C6F, +0xD10D, +0x33AF, +0x0C2F, +0xD375, +0x33AF, +0x0C1F, +0x9006, +0x0180, +0x7D00, +0x0181, +0xAAAA, +0x0182, +0x28C6, +0xD183, +0x0184, +0x2C00, +0x0185, +0x6408, +0x0800, +0x01AD, +0x01AD, +0x0080, +0x01AF, +0x0016, +0xD9B6, +0x0807, +0x0313, +0x33FE, +0x0C1F, +0x0C63, +0x864B, +0x19AD, +0x2B47, +0x0180, +0x7D00, +0x0181, +0xAAAA, +0x0182, +0x2886, +0xD183, +0x0184, +0x2C00, +0x0185, +0x6408, +0x0800, +0x01AD, +0x01AD, +0x0080, +0x01AF, +0x0016, +0xD9B6, +0x0807, +0x032D, +0x33FE, +0x0C1F, +0x0C43, +0x864B, +0x0807, +0x0330, +0x868A, +0x31A5, +0x0801, +0x0020, +0x5023, +0x31A1, +0x080E, +0x00FF, +0x13EF, +0x33AE, +0x3180, +0x2179, +0x2348, +0x5581, +0x43ED, +0x31B8, +0x080D, +0x00FF, +0x542D, +0x55AC, +0x43ED, +0x31B9, +0x0800, +0x0179, +0x30AD, +0x0807, +0x034C, +0x0C04, +0x86B5, +0x080E, +0x00FF, +0x1BEF, +0x33AE, +0x2B48, +0x0800, +0x0348, +0x0801, +0x0347, +0x0807, +0x0358, +0x866E, +0x1B48, +0x080F, +0x00FF, +0x2BEF, +0x33AF, +0x0800, +0x0348, +0x0801, +0x0347, +0x0802, +0x0179, +0x0807, +0x0366, +0x868A, +0x0807, +0x036A, +0x0C04, +0x869C, +0x0180, +0x7D00, +0x0181, +0x5555, +0x0182, +0x14C6, +0xD183, +0x0184, +0x2C00, +0x0185, +0x6408, +0x0800, +0x01AD, +0x01AD, +0x0080, +0x01AF, +0x0018, +0xD9B6, +0x0807, +0x0382, +0x33FE, +0x0C1F, +0x0C63, +0x864B, +0x19AD, +0x2B47, +0x0180, +0x7D00, +0x0181, +0x5555, +0x0182, +0x1486, +0xD183, +0x0184, +0x2C00, +0x0185, +0x6408, +0x0800, +0x01AD, +0x01AD, +0x0080, +0x01AF, +0x0018, +0xD9B6, +0x0807, +0x039C, +0x33FE, +0x0C1F, +0x0C43, +0x864B, +0x0807, +0x039F, +0x868A, +0x31A5, +0x0801, +0x0020, +0x5023, +0x31A1, +0x080E, +0x00FF, +0x13F0, +0x33AE, +0x3180, +0x217A, +0x2348, +0x5581, +0x43ED, +0x31B8, +0x080D, +0x00FF, +0x542D, +0x55AC, +0x43ED, +0x31B9, +0x0800, +0x017A, +0x30AD, +0x0807, +0x03BB, +0x0C04, +0x86B5, +0x080E, +0x00FF, +0x1BF0, +0x33AE, +0x2B48, +0x0800, +0x0348, +0x0801, +0x0347, +0x0807, +0x03C7, +0x866E, +0x1B48, +0x080F, +0x00FF, +0x2BF0, +0x33AF, +0x0800, +0x0348, +0x0801, +0x0347, +0x0802, +0x017A, +0x0807, +0x03D5, +0x868A, +0x0807, +0x03D9, +0x0C04, +0x869C, +0x82CB, +0x0180, +0x7D00, +0x0181, +0xAAAA, +0x0182, +0x28C6, +0xD183, +0x0184, +0x2C00, +0x0185, +0x6408, +0x0800, +0x01AD, +0x01AD, +0x0080, +0x01AF, +0x0010, +0xD9B6, +0x0807, +0x03F2, +0x33FE, +0x0C1F, +0x0C63, +0x864B, +0x19AD, +0x2B47, +0x0180, +0x7D00, +0x0181, +0xAAAA, +0x0182, +0x2886, +0xD183, +0x0184, +0x2C00, +0x0185, +0x6408, +0x0800, +0x01AD, +0x01AD, +0x0080, +0x01AF, +0x0010, +0xD9B6, +0x0807, +0x040C, +0x33FE, +0x0C1F, +0x0C43, +0x864B, +0x0807, +0x040F, +0x868A, +0x31A5, +0x0801, +0x0020, +0x5023, +0x134B, +0x3180, +0x2173, +0x2348, +0x558D, +0x43ED, +0x31B8, +0x0801, +0x0020, +0x5061, +0x0801, +0x00FF, +0x55A1, +0x55AC, +0x43ED, +0x31B9, +0x0800, +0x0173, +0x30AD, +0x0807, +0x042A, +0x0C04, +0x86B5, +0x1B4B, +0x2B48, +0x0800, +0x0348, +0x0801, +0x0347, +0x0807, +0x0433, +0x866E, +0x1B48, +0x2B4B, +0x0800, +0x0348, +0x0801, +0x0347, +0x0802, +0x0173, +0x0807, +0x043E, +0x868A, +0x0807, +0x0442, +0x0C04, +0x869C, +0x0180, +0x7D00, +0x0181, +0x5555, +0x0182, +0x14C6, +0xD183, +0x0184, +0x2C00, +0x0185, +0x6408, +0x0800, +0x01AD, +0x01AD, +0x0080, +0x01AF, +0x0012, +0xD9B6, +0x0807, +0x045A, +0x33FE, +0x0C1F, +0x0C63, +0x864B, +0x19AD, +0x2B47, +0x0180, +0x7D00, +0x0181, +0x5555, +0x0182, +0x1486, +0xD183, +0x0184, +0x2C00, +0x0185, +0x6408, +0x0800, +0x01AD, +0x01AD, +0x0080, +0x01AF, +0x0012, +0xD9B6, +0x0807, +0x0474, +0x33FE, +0x0C1F, +0x0C43, +0x864B, +0x0807, +0x0477, +0x868A, +0x31A5, +0x0801, +0x0020, +0x5023, +0x134D, +0x3180, +0x2175, +0x2348, +0x558D, +0x43ED, +0x31B8, +0x0801, +0x0020, +0x5061, +0x0801, +0x00FF, +0x55A1, +0x55AC, +0x43ED, +0x31B9, +0x0800, +0x0175, +0x30AD, +0x0807, +0x0492, +0x0C04, +0x86B5, +0x1B4D, +0x2B48, +0x0800, +0x0348, +0x0801, +0x0347, +0x0807, +0x049B, +0x866E, +0x1B48, +0x2B4D, +0x0800, +0x0348, +0x0801, +0x0347, +0x0802, +0x0175, +0x0807, +0x04A6, +0x868A, +0x0807, +0x04AA, +0x0C04, +0x869C, +0x82D4, +0x0180, +0x7D00, +0x0181, +0xAAAA, +0x0182, +0x2846, +0xD183, +0x0184, +0x2C00, +0x0185, +0x6408, +0x0800, +0x01AD, +0x01AD, +0x0080, +0x01AF, +0x0016, +0xD9B6, +0x0807, +0x04C3, +0x33FE, +0x0C1F, +0x0C63, +0x864B, +0x19AD, +0x2B47, +0x0180, +0x7D00, +0x0181, +0xAAAA, +0x0182, +0x2806, +0xD183, +0x0184, +0x2C00, +0x0185, +0x6408, +0x0800, +0x01AD, +0x01AD, +0x0080, +0x01AF, +0x0016, +0xD9B6, +0x0807, +0x04DD, +0x33FE, +0x0C1F, +0x0C43, +0x864B, +0x0807, +0x04E0, +0x868A, +0x31A5, +0x0801, +0x0020, +0x5023, +0x080E, +0xFF00, +0x13EF, +0x33AE, +0x3180, +0x2179, +0x2348, +0x558D, +0x43ED, +0x31B8, +0x080D, +0x00FF, +0x542D, +0x55AC, +0x43ED, +0x31B9, +0x0800, +0x0179, +0x30AD, +0x0807, +0x04FB, +0x0C24, +0x86B5, +0x080E, +0xFF00, +0x1BEF, +0x33AE, +0x2B48, +0x0800, +0x0348, +0x0801, +0x0347, +0x0807, +0x0507, +0x866E, +0x1B48, +0x080F, +0xFF00, +0x2BEF, +0x33AF, +0x0800, +0x0348, +0x0801, +0x0347, +0x0802, +0x0179, +0x0807, +0x0515, +0x868A, +0x0807, +0x0519, +0x0C24, +0x869C, +0x0180, +0x7D00, +0x0181, +0x5555, +0x0182, +0x1446, +0xD183, +0x0184, +0x2C00, +0x0185, +0x6408, +0x0800, +0x01AD, +0x01AD, +0x0080, +0x01AF, +0x0018, +0xD9B6, +0x0807, +0x0531, +0x33FE, +0x0C1F, +0x0C63, +0x864B, +0x19AD, +0x2B47, +0x0180, +0x7D00, +0x0181, +0x5555, +0x0182, +0x1406, +0xD183, +0x0184, +0x2C00, +0x0185, +0x6408, +0x0800, +0x01AD, +0x01AD, +0x0080, +0x01AF, +0x0018, +0xD9B6, +0x0807, +0x054B, +0x33FE, +0x0C1F, +0x0C43, +0x864B, +0x0807, +0x054E, +0x868A, +0x31A5, +0x0801, +0x0020, +0x5023, +0x31A1, +0x080E, +0xFF00, +0x13F0, +0x33AE, +0x3180, +0x217A, +0x2348, +0x5581, +0x43ED, +0x31B8, +0x080D, +0x00FF, +0x542D, +0x55AC, +0x43ED, +0x31B9, +0x0800, +0x017A, +0x30AD, +0x0807, +0x056A, +0x0C24, +0x86B5, +0x080E, +0xFF00, +0x1BF0, +0x33AE, +0x2B48, +0x0800, +0x0348, +0x0801, +0x0347, +0x0807, +0x0576, +0x866E, +0x1B48, +0x080F, +0xFF00, +0x2BF0, +0x33AF, +0x0800, +0x0348, +0x0801, +0x0347, +0x0802, +0x017A, +0x0807, +0x0584, +0x868A, +0x0807, +0x0588, +0x0C24, +0x869C, +0x080E, +0xFF00, +0x1BEF, +0x080E, +0x00FF, +0x13EF, +0x33AE, +0x518D, +0x422D, +0x2B51, +0x080E, +0xFF00, +0x1BF0, +0x080E, +0x00FF, +0x13F0, +0x33AE, +0x518D, +0x422D, +0x2B52, +0x82DD, +0x0180, +0x7D00, +0x0181, +0xAAAA, +0x0182, +0x2846, +0xD183, +0x0184, +0x2C00, +0x0185, +0x6408, +0x0800, +0x01AD, +0x01AD, +0x0080, +0x01AF, +0x0011, +0xD9B6, +0x0807, +0x05B5, +0x33FE, +0x0C1F, +0x0C63, +0x864B, +0x19AD, +0x2B47, +0x0180, +0x7D00, +0x0181, +0xAAAA, +0x0182, +0x2806, +0xD183, +0x0184, +0x2C00, +0x0185, +0x6408, +0x0800, +0x01AD, +0x01AD, +0x0080, +0x01AF, +0x0011, +0xD9B6, +0x0807, +0x05CF, +0x33FE, +0x0C1F, +0x0C43, +0x864B, +0x0807, +0x05D2, +0x868A, +0x31A5, +0x0801, +0x0020, +0x5023, +0x134C, +0x3180, +0x2174, +0x2348, +0x558D, +0x43ED, +0x31B8, +0x0801, +0x0020, +0x5061, +0x0801, +0x00FF, +0x55A1, +0x55AC, +0x43ED, +0x31B9, +0x0800, +0x0174, +0x30AD, +0x0807, +0x05ED, +0x0C24, +0x86B5, +0x1B4C, +0x2B48, +0x0800, +0x0348, +0x0801, +0x0347, +0x0807, +0x05F6, +0x866E, +0x1B48, +0x2B4C, +0x0800, +0x0348, +0x0801, +0x0347, +0x0802, +0x0174, +0x0807, +0x0601, +0x868A, +0x0807, +0x0605, +0x0C24, +0x869C, +0x0180, +0x7D00, +0x0181, +0x5555, +0x0182, +0x1446, +0xD183, +0x0184, +0x2C00, +0x0185, +0x6408, +0x0800, +0x01AD, +0x01AD, +0x0080, +0x01AF, +0x0013, +0xD9B6, +0x0807, +0x061D, +0x33FE, +0x0C1F, +0x0C63, +0x864B, +0x19AD, +0x2B47, +0x0180, +0x7D00, +0x0181, +0x5555, +0x0182, +0x1406, +0xD183, +0x0184, +0x2C00, +0x0185, +0x6408, +0x0800, +0x01AD, +0x01AD, +0x0080, +0x01AF, +0x0013, +0xD9B6, +0x0807, +0x0637, +0x33FE, +0x0C1F, +0x0C43, +0x864B, +0x0807, +0x063A, +0x868A, +0x31A5, +0x0801, +0x0020, +0x5023, +0x134E, +0x3180, +0x2176, +0x2348, +0x558D, +0x43ED, +0x31B8, +0x0801, +0x0020, +0x5061, +0x0801, +0x00FF, +0x55A1, +0x55AC, +0x43ED, +0x31B9, +0x0800, +0x0176, +0x30AD, +0x0807, +0x0655, +0x0C24, +0x86B5, +0x1B4E, +0x2B48, +0x0800, +0x0348, +0x0801, +0x0347, +0x0807, +0x065E, +0x866E, +0x1B48, +0x2B4E, +0x0800, +0x0348, +0x0801, +0x0347, +0x0802, +0x0176, +0x0807, +0x0669, +0x868A, +0x0807, +0x066D, +0x0C24, +0x869C, +0x82E6, +0x19AD, +0x31A4, +0x3825, +0x5085, +0x31A5, +0x4225, +0x3C01, +0x338D, +0x55A5, +0xB67B, +0x330D, +0xA67E, +0x8689, +0xA682, +0x380D, +0x8689, +0x5E20, +0xB689, +0x3580, +0x8689, +0x332D, +0xA685, +0x8689, +0x5A20, +0x31A2, +0x430D, +0xA680, +0x9007, +0x080E, +0x1FE0, +0x196E, +0x33AE, +0x31A3, +0x080E, +0x1000, +0x196E, +0x33AE, +0x31A4, +0xA696, +0x869A, +0x080D, +0x0100, +0x546D, +0x31A3, +0x308D, +0x9007, +0xA6A0, +0x308D, +0xA6AA, +0x86A3, +0x308D, +0xA6A3, +0x86AA, +0x3805, +0x5065, +0x31A4, +0x430D, +0xA6B1, +0x308D, +0x86AE, +0x3805, +0x5465, +0xB6AE, +0x86B1, +0x3C02, +0x35A1, +0x86B2, +0x384D, +0x29AD, +0xD9B6, +0x9007, +0xA6B9, +0x308D, +0xA6C3, +0x86BC, +0x308D, +0xA6BC, +0x86C3, +0x3805, +0x5065, +0x31A4, +0x430D, +0xA6C9, +0x308D, +0x86C7, +0x3805, +0x5465, +0xB6C7, +0x86C9, +0x31BC, +0x86CA, +0x30BC, +0x9007, +0x0180, +0x00FF, +0x0181, +0xAAAA, +0x0182, +0x2806, +0x0183, +0x0800, +0x0184, +0x7060, +0x0185, +0x2402, +0x0160, +0x0C07, +0xD161, +0x0162, +0x00C6, +0x0163, +0x1000, +0xD164, +0x0165, +0x3000, +0x0166, +0x7828, +0x0167, +0x21A2, +0xD168, +0x1B38, +0xA712, +0x1BCC, +0x31A1, +0x1B51, +0x502D, +0x31A1, +0x0807, +0x06F0, +0x8DF4, +0xA6F3, +0x5061, +0x86F4, +0x5461, +0xB6F6, +0x86FE, +0x31A1, +0x430D, +0xA6FB, +0x302D, +0x86FF, +0x080D, +0x00FF, +0x86FF, +0x0C0D, +0x080F, +0x00FF, +0x2969, +0x33AF, +0x1BCD, +0x31A1, +0x1B52, +0x502D, +0x31A1, +0x080F, +0xFF00, +0x2969, +0x33AF, +0x6C00, +0x080E, +0xFF00, +0x197B, +0x33AE, +0x31B8, +0x0180, +0x00FF, +0x0162, +0x0084, +0x0165, +0xB000, +0x1B38, +0xA73B, +0x1B51, +0x31A1, +0x13CC, +0x0807, +0x0720, +0x8DF4, +0xA724, +0x5061, +0x558D, +0x8726, +0x506C, +0x55A1, +0x31A1, +0xB729, +0x8730, +0x430D, +0xA72D, +0x302D, +0x8731, +0x080D, +0x00FF, +0x8731, +0x0C0D, +0x080F, +0x00FF, +0x2969, +0x33AF, +0x6C00, +0x080E, +0xFF00, +0x197B, +0x33AE, +0x31B9, +0x0180, +0x00FF, +0x0181, +0x5555, +0x0182, +0x1406, +0x0162, +0x00C6, +0x0163, +0x2000, +0x0165, +0x3000, +0x080F, +0x03FF, +0xD960, +0x33AF, +0x1B38, +0xA759, +0x1352, +0x1B51, +0x55B8, +0x518D, +0x410D, +0x2969, +0x6C00, +0x080E, +0x00FF, +0x197B, +0x33AE, +0x31BA, +0x0180, +0x00FF, +0x0162, +0x0084, +0x0165, +0xB000, +0x080F, +0x03FF, +0xD960, +0x33AF, +0x1B38, +0xA793, +0x1352, +0x1B51, +0x55B9, +0x51AC, +0x410D, +0x2969, +0x6C00, +0x080E, +0x00FF, +0x197B, +0x33AE, +0x31BB, +0x0C2F, +0xDB75, +0x33AF, +0x0C6F, +0x010D, +0x0002, +0x33AF, +0xD3A6, +0x03A6, +0x000A, +0x5738, +0x424D, +0x532D, +0xD9AE, +0x29AD, +0x01AF, +0x0016, +0xD9B6, +0x577A, +0x424D, +0x536D, +0x29AD, +0x01AF, +0x0018, +0xD9B6, +0xD1AE, +0xD3A6, +0x7000, +0x0C6F, +0xD10D, +0x33AF, +0x0C2F, +0xD375, +0x33AF, +0x0180, +0x01FF, +0x0181, +0xFFFF, +0x0182, +0x3C86, +0xD183, +0x0160, +0x0C10, +0x0161, +0x0009, +0x0162, +0x00C2, +0xD163, +0xD165, +0x0166, +0x792B, +0x0168, +0x4925, +0x1B38, +0xA82D, +0x0807, +0x07AD, +0x33FE, +0x0C1F, +0x89C5, +0x1959, +0x1959, +0x31B6, +0x0807, +0x07B3, +0x8931, +0x081C, +0x0349, +0x0EA1, +0x0C17, +0x3B85, +0x080D, +0x002F, +0x5C2D, +0x54AD, +0xB7BE, +0x87F9, +0x302D, +0xA7C1, +0x87F9, +0x3B85, +0x0CED, +0x54AD, +0xA7C6, +0x87DB, +0x0DED, +0x54AD, +0xA7CA, +0x87DB, +0x0EED, +0x54AD, +0xA7CE, +0x87DB, +0x0FED, +0x54AD, +0xA7D2, +0x87DB, +0x080D, +0x0027, +0x54AD, +0xA7D7, +0x87DB, +0x5C21, +0x31A1, +0x5837, +0x31B7, +0x5A3C, +0x1B4A, +0x29B4, +0xD9B8, +0x1959, +0x1959, +0x31A2, +0x5444, +0xB7E5, +0x87F9, +0x5462, +0xB7E8, +0x87F9, +0x6620, +0x080E, +0x7FFF, +0x1988, +0x33AE, +0x31A2, +0x4022, +0x080E, +0x7FFF, +0x1986, +0x33AE, +0x31A5, +0x4025, +0x426D, +0x55A5, +0x55A2, +0xB7B7, +0x32E0, +0x3B81, +0x1B47, +0x55A1, +0xA7FF, +0x8807, +0xB802, +0x5A3C, +0x8803, +0x5E3C, +0x1B4A, +0x29B4, +0xD9B8, +0x87FA, +0x0C17, +0x1959, +0x1959, +0x31A2, +0x5444, +0xB80E, +0x8810, +0x5462, +0xB813, +0x0807, +0x0813, +0x8917, +0x1959, +0x1959, +0x31A2, +0x5444, +0xB81F, +0x5E3C, +0x1B4A, +0x29B4, +0xD9B8, +0x5E3C, +0x5857, +0x8827, +0x5462, +0xB82D, +0x5A3C, +0x1B4A, +0x29B4, +0xD9B8, +0x5A3C, +0x5840, +0x1B4A, +0x29B4, +0xD9B8, +0x0807, +0x082D, +0x8917, +0x0180, +0x01FF, +0x0182, +0x3CC6, +0x1B38, +0xA8BF, +0x0807, +0x0838, +0x33FE, +0x0C1F, +0x89C5, +0x0C2F, +0xDB75, +0x33AF, +0x0C6F, +0x010D, +0x0002, +0x33AF, +0xD3A6, +0x03A6, +0x000A, +0x5738, +0x424D, +0x55B8, +0xD9AE, +0x29AD, +0x01AF, +0x0016, +0xD9B6, +0x577A, +0x424D, +0x55BA, +0x29AD, +0x01AF, +0x0018, +0xD9B6, +0xD1AE, +0xD3A6, +0x7000, +0x0C6F, +0xD10D, +0x33AF, +0x0C2F, +0xD375, +0x33AF, +0x081C, +0x0349, +0x0EA1, +0x3B85, +0x0C0D, +0x582D, +0x55A5, +0xB863, +0x889C, +0x302D, +0xA866, +0x889C, +0x3B85, +0x0D0D, +0x54AD, +0xA86B, +0x8881, +0x0E0D, +0x54AD, +0xA86F, +0x8881, +0x0F0D, +0x54AD, +0xA873, +0x8881, +0x080D, +0x0020, +0x54AD, +0xA878, +0x8881, +0x080D, +0x0028, +0x54AD, +0xA87D, +0x8881, +0x5C21, +0x31A1, +0x5837, +0x31B7, +0x5E3C, +0x1B4A, +0x29B4, +0xD9B8, +0x1959, +0x1959, +0x31A2, +0x5444, +0xB88B, +0x889C, +0x5462, +0xB88E, +0x889C, +0x6620, +0x080E, +0x7FFF, +0x1988, +0x33AE, +0x31A2, +0x4022, +0x080E, +0x7FFF, +0x1986, +0x33AE, +0x426D, +0x544D, +0xB85D, +0x32ED, +0x300D, +0x080F, +0xFF00, +0x2BEA, +0x33AF, +0x32ED, +0x080F, +0x00FF, +0x2BEA, +0x33AF, +0x56E0, +0xB8B5, +0x5417, +0x5C2D, +0x422D, +0x31A0, +0x5C6D, +0xB8B3, +0x0C6C, +0x540C, +0x31AC, +0x88B9, +0x0C0C, +0x88BE, +0x582D, +0x422D, +0x586D, +0x31AC, +0x5D2D, +0xB8BC, +0x88BE, +0x0D2C, +0x88BE, +0x8998, +0x1B38, +0xA8D3, +0x3B8D, +0x331C, +0x31B8, +0x2B7B, +0x0807, +0x08C9, +0x32CD, +0x8931, +0x1959, +0x1959, +0x31A2, +0x5482, +0xB8D0, +0x5462, +0xB8D3, +0x0807, +0x08D3, +0x8917, +0x0807, +0x08D6, +0x8DF4, +0x31A2, +0xA8E0, +0x573C, +0xB8DC, +0x462D, +0x88DD, +0x422D, +0x532D, +0x546D, +0x88E7, +0x573C, +0xB8E4, +0x462D, +0x88E5, +0x422D, +0x532D, +0x506D, +0x31A1, +0xB8EB, +0x0C0D, +0x88F1, +0x430D, +0xA8EF, +0x302D, +0x88F1, +0x080D, +0x00FF, +0x080F, +0x00FF, +0x2BE8, +0x33AF, +0x304D, +0xA8FF, +0x577A, +0xB8FB, +0x462D, +0x88FC, +0x422D, +0x536D, +0x546D, +0x8906, +0x577A, +0xB903, +0x462D, +0x8904, +0x422D, +0x536D, +0x506D, +0x31A1, +0xB90A, +0x0C0D, +0x8910, +0x430D, +0xA90E, +0x302D, +0x8910, +0x080D, +0x00FF, +0x080F, +0xFF00, +0x2BE8, +0x33AF, +0x0C1F, +0x33FE, +0x88EC, +0x32CD, +0x2959, +0x080F, +0x0020, +0xD906, +0x33AF, +0x0E0F, +0xD106, +0x33AF, +0x0C8E, +0x1919, +0x33AE, +0xA920, +0x0E0F, +0xD906, +0x33AF, +0x0C8E, +0x1919, +0x33AE, +0xA92C, +0x8927, +0x080F, +0x0020, +0xD106, +0x33AF, +0x9007, +0x31A0, +0x0803, +0x1000, +0x546D, +0xB938, +0x0C03, +0x8939, +0x31A3, +0x0804, +0x1000, +0x5080, +0x31A0, +0x0804, +0x4000, +0x55A4, +0xB944, +0x0804, +0x4000, +0x8945, +0x3004, +0x9007, +0x1B53, +0x31A5, +0x3181, +0x302D, +0xA94C, +0x8965, +0x0CED, +0x54AD, +0xA950, +0x8963, +0x0DED, +0x54AD, +0xA954, +0x8963, +0x0EED, +0x54AD, +0xA958, +0x8963, +0x0FED, +0x54AD, +0xA95C, +0x8963, +0x080D, +0x0027, +0x54AD, +0xA961, +0x8963, +0x5C21, +0x31A1, +0x5825, +0x8949, +0x1B49, +0x31A0, +0x54AD, +0xB981, +0x5405, +0x31A1, +0x081C, +0x0349, +0x3B85, +0x080D, +0x002F, +0x5C2D, +0x54AD, +0xB974, +0x897E, +0x302D, +0xA977, +0x897E, +0x5C21, +0x31A1, +0x5A3C, +0x1B4A, +0x29B4, +0xD9B8, +0x896D, +0x0C1F, +0x33FE, +0x8721, +0x54A0, +0x31A1, +0x081C, +0x0349, +0x3B85, +0x0C0D, +0x582D, +0x55A5, +0xB98B, +0x8995, +0x302D, +0xA98E, +0x8995, +0x5C21, +0x31A1, +0x5E3C, +0x1B4A, +0x29B4, +0xD9B8, +0x8985, +0x0C1F, +0x33FE, +0x8721, +0x1B53, +0x31A5, +0x3181, +0x302D, +0xA99E, +0x89B7, +0x0CED, +0x54AD, +0xA9A2, +0x89B5, +0x0DED, +0x54AD, +0xA9A6, +0x89B5, +0x0EED, +0x54AD, +0xA9AA, +0x89B5, +0x0FED, +0x54AD, +0xA9AE, +0x89B5, +0x080D, +0x0027, +0x54AD, +0xA9B3, +0x89B5, +0x5C21, +0x31A1, +0x5825, +0x899B, +0x1B49, +0x31A0, +0x54AD, +0xB9D1, +0x5405, +0x31A1, +0x081C, +0x0349, +0x3B85, +0x080D, +0x002F, +0x5C2D, +0x54AD, +0xB9C6, +0x89D0, +0x302D, +0xA9C9, +0x89D0, +0x5C21, +0x31A1, +0x5A3C, +0x1B4A, +0x29B4, +0xD9B8, +0x89BF, +0x88BF, +0x54A0, +0x31A1, +0x081C, +0x0349, +0x3B85, +0x0C0D, +0x582D, +0x55A5, +0xB9DB, +0x89E5, +0x302D, +0xA9DE, +0x89E5, +0x5C21, +0x31A1, +0x5E3C, +0x1B4A, +0x29B4, +0xD9B8, +0x89D5, +0x88BF, +0x0180, +0x00FF, +0x0181, +0xAAAA, +0x0182, +0x2806, +0x0183, +0x0800, +0x0184, +0x7060, +0x0185, +0x2402, +0x300D, +0x080F, +0x03E0, +0x2982, +0x33AF, +0x0FEF, +0x0182, +0x0006, +0x33AF, +0x080F, +0x0800, +0xD183, +0x33AF, +0x0160, +0x0C07, +0xD161, +0x0162, +0x00C6, +0x0163, +0x1000, +0xD164, +0x0165, +0x3000, +0x0166, +0x7828, +0x0167, +0x21A2, +0xD168, +0x302D, +0x080F, +0xF000, +0x2965, +0x33AF, +0x304D, +0x080F, +0x03FF, +0x2960, +0x33AF, +0x306D, +0xAA4B, +0x300D, +0x5CCD, +0xAA1E, +0x8A21, +0x300D, +0x5C4D, +0xAA33, +0x1B51, +0x13CC, +0x518D, +0x31B7, +0x430D, +0xAA2B, +0x32ED, +0xBA2D, +0x0C17, +0x8A2D, +0x0817, +0x00FF, +0x32ED, +0x080F, +0x00FF, +0x2969, +0x33AF, +0x8A50, +0x300D, +0x5C8D, +0xAA37, +0x8A39, +0x300D, +0xAA50, +0x1B51, +0x13CC, +0x558D, +0x31B7, +0xBA40, +0x0C17, +0x8A45, +0x430D, +0xAA43, +0x8A45, +0x0817, +0x00FF, +0x32ED, +0x080F, +0x00FF, +0x2969, +0x33AF, +0x8A50, +0x308D, +0x080F, +0x00FF, +0x2969, +0x33AF, +0x6C00, +0x080E, +0xFF00, +0x197B, +0x33AE, +0x0C1F, +0x9007, +0x0180, +0x00FF, +0x0181, +0x5555, +0x0182, +0x1406, +0x0183, +0x0800, +0x0184, +0x7060, +0x0185, +0x2402, +0x300D, +0x080F, +0x03E0, +0x2982, +0x33AF, +0x0FEF, +0x0182, +0x0006, +0x33AF, +0x080F, +0x0800, +0xD183, +0x33AF, +0x0160, +0x0C07, +0xD161, +0x0162, +0x00C6, +0x0163, +0x2000, +0xD164, +0x0165, +0x3000, +0x0166, +0x7828, +0x0167, +0x21A2, +0xD168, +0x302D, +0x080F, +0xF000, +0x2965, +0x33AF, +0x304D, +0x080F, +0x03FF, +0x2960, +0x33AF, +0x306D, +0xAABC, +0x300D, +0x5CCD, +0xAA8F, +0x8A92, +0x300D, +0x5C4D, +0xAAA4, +0x1B52, +0x13CD, +0x518D, +0x31B7, +0x430D, +0xAA9C, +0x32ED, +0xBA9E, +0x0C17, +0x8A9E, +0x0817, +0x00FF, +0x32ED, +0x080F, +0xFF00, +0x2969, +0x33AF, +0x8AC1, +0x300D, +0x5C8D, +0xAAA8, +0x8AAA, +0x300D, +0xAAC1, +0x1B52, +0x13CD, +0x558D, +0x31B7, +0xBAB1, +0x0C17, +0x8AB6, +0x430D, +0xAAB4, +0x8AB6, +0x0817, +0x00FF, +0x32ED, +0x080F, +0xFF00, +0x2969, +0x33AF, +0x8AC1, +0x308D, +0x080F, +0xFF00, +0x2969, +0x33AF, +0x6C00, +0x080E, +0x00FF, +0x197B, +0x33AE, +0x0C1F, +0x9007, +0x0800, +0x00F5, +0x5418, +0xBACF, +0x5419, +0xBACF, +0x8AD5, +0x080F, +0x1C00, +0x03F6, +0x0003, +0x33AF, +0x8AE3, +0x541A, +0xBADE, +0x541B, +0xBADE, +0x080F, +0x1C00, +0xD3F6, +0x33AF, +0x8AE3, +0x080F, +0x1C00, +0x03F6, +0x0005, +0x33AF, +0x0800, +0x00F5, +0x5418, +0xBAEA, +0x541A, +0xBAEA, +0x8AF3, +0x5419, +0xBAF3, +0x541B, +0xBAF3, +0x080F, +0x6000, +0xDBF6, +0x33AF, +0x8B0F, +0x5419, +0xBAF8, +0x541B, +0xBAF8, +0x8B02, +0x5418, +0xBB02, +0x541A, +0xBB02, +0x080F, +0x6000, +0x03F6, +0x0002, +0x33AF, +0x8B0F, +0x571A, +0xBB06, +0x3302, +0x8B07, +0x3342, +0x573B, +0xBB0B, +0x3323, +0x8B0C, +0x3363, +0x5443, +0xBAFC, +0x8AEE, +0x0C1F, +0x9007, +0x080E, +0x6000, +0x1BF6, +0x33AE, +0x5C2D, +0xAB1C, +0x1352, +0x5379, +0x422D, +0x558D, +0x8B27, +0x080E, +0x6000, +0x1BF6, +0x33AE, +0x5C4D, +0xAB27, +0x1351, +0x5358, +0x422D, +0x558D, +0x8B27, +0xBB2C, +0x410D, +0x430D, +0x31B7, +0x8B32, +0x31B7, +0x430D, +0xAB30, +0x8B32, +0x0817, +0x00FF, +0x0C1F, +0x9007, +0x080E, +0x00FF, +0x196B, +0x33AE, +0x42AD, +0x0CEF, +0x290B, +0x33AF, +0x080E, +0x03E0, +0x196D, +0x33AE, +0x080F, +0xF800, +0x290B, +0x33AF, +0x080E, +0x1C00, +0x196D, +0x33AE, +0x0CEF, +0x290C, +0x33AF, +0x080E, +0x03C0, +0x196C, +0x33AE, +0x31A0, +0x080F, +0x0078, +0x290B, +0x33AF, +0x080E, +0x003F, +0x196C, +0x33AE, +0xAB5A, +0x8B5C, +0x5820, +0x31A0, +0x300D, +0x080F, +0x0780, +0x290B, +0x33AF, +0x32ED, +0x080F, +0x07F8, +0x290C, +0x33AF, +0x080E, +0x0FFF, +0x196F, +0x33AE, +0x42AD, +0x080F, +0x007F, +0x291A, +0x33AF, +0x080E, +0x0FFF, +0x1970, +0x33AE, +0x42AD, +0x080F, +0x3F80, +0x291A, +0x33AF, +0x080E, +0x0FFF, +0x1971, +0x33AE, +0x42AD, +0x080F, +0x007F, +0x291B, +0x33AF, +0x080E, +0x0FFF, +0x1972, +0x33AE, +0x42AD, +0x080F, +0x3F80, +0x291B, +0x33AF, +0x080F, +0x0800, +0xD90C, +0x33AF, +0x0C4F, +0xD90D, +0x33AF, +0x0306, +0x000C, +0x0C2E, +0x1919, +0x33AE, +0xAB98, +0x8B93, +0x0306, +0x0008, +0x080F, +0x0800, +0xD10C, +0x33AF, +0x0C4F, +0xD10D, +0x33AF, +0x0C1F, +0x9007, +0x080E, +0x0020, +0x1B6F, +0x33AE, +0xABF4, +0x8BF7, +0x1B53, +0x31A1, +0x1B49, +0x31B7, +0x0802, +0x0349, +0x0C25, +0x0807, +0x0BB3, +0x8C0F, +0x0180, +0x003F, +0x0181, +0xAAAA, +0x0182, +0x2802, +0x0183, +0x0800, +0x0184, +0x7060, +0x0185, +0x2402, +0x0807, +0x0BC4, +0x33FE, +0x0C1F, +0x89C5, +0x0160, +0x0C07, +0xD161, +0x0162, +0x0042, +0x0163, +0x3000, +0xD164, +0x0165, +0x3000, +0x0166, +0x7828, +0x0167, +0x21A2, +0xD168, +0x330D, +0x410D, +0x530D, +0x2969, +0x6E00, +0x197B, +0x430D, +0x31BA, +0xD162, +0x0165, +0xB000, +0x332D, +0x410D, +0x532D, +0x2969, +0x6E00, +0x197B, +0x430D, +0x31BB, +0x577A, +0xBBE9, +0x0C0D, +0x080F, +0x00FF, +0x2BE9, +0x33AE, +0x32E1, +0x0C05, +0x0802, +0x0349, +0x0807, +0x0BF4, +0x8C0F, +0x33FE, +0x0C1F, +0x87EA, +0x1BF2, +0x5C4D, +0xABFD, +0x1B52, +0x13CD, +0x8BFF, +0x1B51, +0x13CC, +0x31A1, +0x518D, +0x31A0, +0x430D, +0xAC06, +0x300D, +0x8C08, +0x080D, +0x00FF, +0x31B8, +0x302D, +0x558D, +0xBC0D, +0x0C0D, +0x31B9, +0x8BA9, +0x1B49, +0x31A0, +0x30AD, +0xAC18, +0x5401, +0xAC16, +0x8C24, +0xBC1D, +0x8C24, +0x5420, +0xAC1B, +0x8C24, +0xBC1F, +0x8C24, +0x5A22, +0x8C20, +0x5E22, +0x1B4A, +0x29B4, +0xD9B8, +0x8C0F, +0x9007, +0x080F, +0xFF00, +0xD3E9, +0x33AF, +0x080E, +0x00FF, +0x13E8, +0x33AE, +0x0D4D, +0x518D, +0x31A2, +0x080E, +0xFF00, +0x13E8, +0x33AE, +0x0D4D, +0x518D, +0x31A5, +0x0807, +0x0C3A, +0x8DF4, +0xAC40, +0x5062, +0x31A2, +0x5065, +0x31A5, +0x8C48, +0x5462, +0x31A2, +0xBC44, +0x0C02, +0x5465, +0x31A5, +0xBC48, +0x0C05, +0x304D, +0x430D, +0xAC4C, +0x8C4E, +0x0802, +0x00FF, +0x30AD, +0x430D, +0xAC52, +0x8C54, +0x0805, +0x00FF, +0x0807, +0x0C57, +0x8CCB, +0x0800, +0x0349, +0x0802, +0x034A, +0x0803, +0x01B4, +0x3818, +0x0C01, +0x0CA4, +0x0C37, +0x0807, +0x0C64, +0x8D18, +0x080F, +0x03E0, +0x0182, +0x0006, +0x33AF, +0x0807, +0x0C6C, +0x8CD9, +0x080E, +0x00FF, +0x13E8, +0x33AE, +0x0D4D, +0x55AC, +0x31A2, +0x080E, +0xFF00, +0x13E8, +0x33AE, +0x0D4D, +0x55AC, +0x31A5, +0x0807, +0x0C7D, +0x8DF4, +0xAC83, +0x5062, +0x31A2, +0x5065, +0x31A5, +0x8C8B, +0x5462, +0x31A2, +0xBC87, +0x0C02, +0x5465, +0x31A5, +0xBC8B, +0x0C05, +0x0C0D, +0x304D, +0x43ED, +0xAC96, +0x304D, +0x430D, +0xAC93, +0x8C97, +0x0802, +0x00FF, +0x8C97, +0x0C02, +0x30AD, +0x43ED, +0xACA1, +0x30AD, +0x430D, +0xAC9E, +0x8CA2, +0x0805, +0x00FF, +0x8CA2, +0x0C05, +0x0807, +0x0CA5, +0x8CCB, +0x0800, +0x0349, +0x0802, +0x034A, +0x0803, +0x01B4, +0x3818, +0x0801, +0x002F, +0x0D44, +0x0C17, +0x0807, +0x0CB3, +0x8D18, +0x080F, +0x03E0, +0x0182, +0x0004, +0x33AF, +0x0807, +0x0CBB, +0x8CD9, +0x0800, +0x0349, +0x0802, +0x034A, +0x0803, +0x01B4, +0x3818, +0x0C01, +0x0CA4, +0x0C37, +0x0807, +0x0CC8, +0x8D18, +0x33FE, +0x0C1F, +0x896A, +0xD9AE, +0x01AF, +0x0016, +0x304D, +0x29AD, +0xD9B6, +0x01AF, +0x0018, +0x30AD, +0x29AD, +0xD9B6, +0x700F, +0xD1AE, +0x9007, +0x080F, +0x7FFF, +0x0180, +0x07CF, +0x33AF, +0x0181, +0xFFFF, +0x0FEF, +0x0182, +0x0006, +0x080F, +0x4000, +0xD984, +0x080F, +0x1C00, +0x0184, +0x0004, +0x080F, +0x0020, +0xD984, +0x0F0F, +0xD184, +0x33AF, +0x080F, +0x03C0, +0xD184, +0x33AF, +0x080F, +0x0800, +0xD183, +0x33AF, +0x0E81, +0x6660, +0x080E, +0x7FFF, +0x198A, +0x33AE, +0x31A2, +0x080E, +0x7FFF, +0x1986, +0x33AE, +0x544D, +0x31A2, +0x080E, +0xFF00, +0x1BE9, +0x33AE, +0x504D, +0x31A2, +0x430D, +0xAD0E, +0x8D10, +0x0802, +0x00FF, +0x304D, +0x080F, +0xFF00, +0x2BE9, +0x33AF, +0x5C21, +0xACF9, +0x9007, +0x3805, +0x0CED, +0x52ED, +0x54AD, +0xAD1E, +0x8D39, +0x0DED, +0x52ED, +0x54AD, +0xAD23, +0x8D39, +0x0EED, +0x52ED, +0x54AD, +0xAD28, +0x8D39, +0x0FED, +0x52ED, +0x54AD, +0xAD2D, +0x8D39, +0x080D, +0x0027, +0x52ED, +0x54AD, +0xAD33, +0x8D39, +0x308D, +0xAD36, +0x8D46, +0x5C24, +0x31A4, +0x8D3E, +0x32ED, +0xAD3E, +0x308D, +0xAD3E, +0x8D46, +0x32ED, +0xAD42, +0x5A20, +0x8D43, +0x5E20, +0x3C43, +0xD9B8, +0x8D18, +0x9007, +0x1959, +0x1959, +0x31A1, +0x0800, +0x3000, +0x5401, +0xBD54, +0x0800, +0x1000, +0x5420, +0xBD54, +0x0C25, +0x8D5C, +0x1B5E, +0xAD59, +0x0807, +0x0D59, +0x8917, +0x0C05, +0x0C04, +0x8DEC, +0x080E, +0x00FF, +0x1BE9, +0x33AE, +0x31A0, +0x080E, +0xFF00, +0x13EA, +0x080E, +0x00FF, +0x1BEA, +0x33AE, +0x51AC, +0xBD6C, +0x0C01, +0x8D73, +0x31A1, +0x0804, +0x002A, +0x55A4, +0xBD73, +0x0801, +0x002A, +0x302D, +0x080F, +0x00FF, +0x2BEB, +0x33AF, +0x0807, +0x0D7B, +0x8DF4, +0xAD7E, +0x0C03, +0x8D7F, +0x4223, +0x080E, +0x0FE0, +0x196F, +0x33AE, +0x31A2, +0x0804, +0x0040, +0x5482, +0xBD89, +0x0C0D, +0x31A2, +0x4222, +0x5062, +0x55A0, +0x31A0, +0x0C04, +0x0C2E, +0x1BEB, +0xAD93, +0x8D96, +0x300D, +0x51A4, +0x31A4, +0x0C4E, +0x1BEB, +0xAD9A, +0x8D9E, +0x300D, +0x442D, +0x51A4, +0x31A4, +0x0C8E, +0x1BEB, +0xADA2, +0x8DA6, +0x300D, +0x444D, +0x51A4, +0x31A4, +0x0D0E, +0x1BEB, +0xADAA, +0x8DAE, +0x300D, +0x446D, +0x51A4, +0x31A4, +0x0E0E, +0x1BEB, +0xADB2, +0x8DB6, +0x300D, +0x448D, +0x51A4, +0x31A4, +0x080E, +0x0020, +0x1BEB, +0xADBB, +0x8DBF, +0x300D, +0x44AD, +0x51A4, +0x31A4, +0x33AE, +0x308D, +0x46AD, +0x31A4, +0x080E, +0xFF00, +0x1BE9, +0x33AE, +0x31A1, +0x1B5E, +0xADDC, +0x0CA0, +0x5401, +0xBDD0, +0x0805, +0x0060, +0x8DDD, +0x0D40, +0x5401, +0xBDD6, +0x0805, +0x0040, +0x8DDD, +0x0DE0, +0x5401, +0xBDDC, +0x0805, +0x0020, +0x8DDD, +0x0C05, +0x5085, +0x31A4, +0x0C0D, +0x308D, +0x43ED, +0xADE4, +0x8DE6, +0x0C04, +0x8DEC, +0x308D, +0x430D, +0xADEA, +0x8DEC, +0x0804, +0x00FF, +0x1B5E, +0xADF2, +0x308D, +0x33FE, +0x0C1F, +0x8972, +0x308D, +0x8048, +0x080E, +0x1FE0, +0x196E, +0x33AE, +0x31A3, +0x080E, +0x1000, +0x196E, +0x33AE, +0x31A4, +0xAE00, +0x8E04, +0x080D, +0x0100, +0x546D, +0x31A3, +0x308D, +0x9007, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000 diff --git a/target/linux/rockchip/files/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c b/target/linux/rockchip/files/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c new file mode 100644 index 000000000..457648c21 --- /dev/null +++ b/target/linux/rockchip/files/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c @@ -0,0 +1,343 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Rockchip PCIE3.0 phy driver + * + * Copyright (C) 2020 Rockchip Electronics Co., Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Register for RK3568 */ +#define GRF_PCIE30PHY_CON1 0x4 +#define GRF_PCIE30PHY_CON4 0x10 +#define GRF_PCIE30PHY_CON6 0x18 +#define GRF_PCIE30PHY_CON9 0x24 +#define GRF_PCIE30PHY_STATUS0 0x80 +#define SRAM_INIT_DONE(reg) (reg & BIT(14)) + +#define RK3568_BIFURCATION_LANE_0_1 BIT(0) + +/* Register for RK3588 */ +#define PHP_GRF_PCIESEL_CON 0x100 +#define RK3588_PCIE3PHY_GRF_CMN_CON0 0x0 +#define RK3588_PCIE3PHY_GRF_PHY0_STATUS1 0x904 +#define RK3588_PCIE3PHY_GRF_PHY1_STATUS1 0xa04 +#define RK3588_SRAM_INIT_DONE(reg) (reg & BIT(0)) + +#define RK3588_BIFURCATION_LANE_0_1 BIT(0) +#define RK3588_BIFURCATION_LANE_2_3 BIT(1) +#define RK3588_LANE_AGGREGATION BIT(2) + +struct rockchip_p3phy_ops; + +struct rockchip_p3phy_priv { + const struct rockchip_p3phy_ops *ops; + void __iomem *mmio; + /* mode: RC, EP */ + int mode; + /* pcie30_phymode: Aggregation, Bifurcation */ + int pcie30_phymode; + struct regmap *phy_grf; + struct regmap *pipe_grf; + struct reset_control *p30phy; + struct phy *phy; + struct clk_bulk_data *clks; + int num_clks; + int num_lanes; + u32 lanes[4]; +}; + +struct rockchip_p3phy_ops { + int (*phy_init)(struct rockchip_p3phy_priv *priv); +}; + +static u16 phy_fw[] = { + #include "p3phy.fw" +}; + +static int rockchip_p3phy_set_mode(struct phy *phy, enum phy_mode mode, int submode) +{ + struct rockchip_p3phy_priv *priv = phy_get_drvdata(phy); + + /* Actually We don't care EP/RC mode, but just record it */ + switch (submode) { + case PHY_MODE_PCIE_RC: + priv->mode = PHY_MODE_PCIE_RC; + break; + case PHY_MODE_PCIE_EP: + priv->mode = PHY_MODE_PCIE_EP; + break; + default: + dev_err(&phy->dev, "%s, invalid mode\n", __func__); + return -EINVAL; + } + + return 0; +} + +static int rockchip_p3phy_rk3568_init(struct rockchip_p3phy_priv *priv) +{ + struct phy *phy = priv->phy; + bool bifurcation = false; + int ret; + int i; + u32 reg; + + /* Deassert PCIe PMA output clamp mode */ + regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON9, BIT(15) | BIT(31)); + + for (i = 0; i < priv->num_lanes; i++) { + dev_info(&phy->dev, "lane number %d, val %d\n", i, priv->lanes[i]); + if (priv->lanes[i] > 1) + bifurcation = true; + } + + /* Set bifurcation if needed, and it doesn't care RC/EP */ + if (bifurcation) { + dev_info(&phy->dev, "bifurcation enabled\n"); + regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON6, + (0xf << 16) | RK3568_BIFURCATION_LANE_0_1); + regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON1, + BIT(15) | BIT(31)); + } else { + dev_info(&phy->dev, "bifurcation disabled\n"); + regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON6, + (0xf << 16) & ~RK3568_BIFURCATION_LANE_0_1); + } + + regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON4, + (0x0 << 14) | (0x1 << (14 + 16))); //sdram_ld_done + regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON4, + (0x0 << 13) | (0x1 << (13 + 16))); //sdram_bypass + + reset_control_deassert(priv->p30phy); + + ret = regmap_read_poll_timeout(priv->phy_grf, + GRF_PCIE30PHY_STATUS0, + reg, SRAM_INIT_DONE(reg), + 0, 500); + if (ret) { + dev_err(&priv->phy->dev, "%s: lock failed 0x%x, check input refclk and power supply\n", + __func__, reg); + return ret; + } + + regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON9, + (0x3 << 8) | (0x3 << (8 + 16))); //map to access sram + for (i = 0; i < 8192; i++) + writel(phy_fw[i], priv->mmio + (i<<2)); + + regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON9, + (0x0 << 8) | (0x3 << (8 + 16))); + regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON4, + (0x1 << 14) | (0x1 << (14 + 16))); //sdram_ld_done + + dev_info(&priv->phy->dev, "p3phy (fw-d54d0eb) initialized\n"); + return 0; +} + +static const struct rockchip_p3phy_ops rk3568_ops = { + .phy_init = rockchip_p3phy_rk3568_init, +}; + +static int rockchip_p3phy_rk3588_init(struct rockchip_p3phy_priv *priv) +{ + u32 reg = 0; + u8 mode = 0; + int ret; + int i; + + /* Deassert PCIe PMA output clamp mode */ + regmap_write(priv->phy_grf, RK3588_PCIE3PHY_GRF_CMN_CON0, BIT(8) | BIT(24)); + + /* Set bifurcation if needed */ + for (i = 0; i < priv->num_lanes; i++) { + if (!priv->lanes[i]) + mode |= (BIT(i) << 3); + + if (priv->lanes[i] > 1) + mode |= (BIT(i) >> 1); + } + + if (!mode) + reg = RK3588_LANE_AGGREGATION; + else { + if (mode & (BIT(0) | BIT(1))) + reg |= RK3588_BIFURCATION_LANE_0_1; + + if (mode & (BIT(2) | BIT(3))) + reg |= RK3588_BIFURCATION_LANE_2_3; + } + + regmap_write(priv->phy_grf, RK3588_PCIE3PHY_GRF_CMN_CON0, (0x7<<16) | reg); + + /* Set pcie1ln_sel in PHP_GRF_PCIESEL_CON */ + if (!IS_ERR(priv->pipe_grf)) { + reg = (mode & (BIT(6) | BIT(7))) >> 6; + if (reg) + regmap_write(priv->pipe_grf, PHP_GRF_PCIESEL_CON, + (reg << 16) | reg); + } + + reset_control_deassert(priv->p30phy); + + ret = regmap_read_poll_timeout(priv->phy_grf, + RK3588_PCIE3PHY_GRF_PHY0_STATUS1, + reg, RK3588_SRAM_INIT_DONE(reg), + 0, 500); + ret |= regmap_read_poll_timeout(priv->phy_grf, + RK3588_PCIE3PHY_GRF_PHY1_STATUS1, + reg, RK3588_SRAM_INIT_DONE(reg), + 0, 500); + if (ret) + pr_err("%s: lock failed 0x%x, check input refclk and power supply\n", + __func__, reg); + return ret; +} + +static const struct rockchip_p3phy_ops rk3588_ops = { + .phy_init = rockchip_p3phy_rk3588_init, +}; + +static int rochchip_p3phy_init(struct phy *phy) +{ + struct rockchip_p3phy_priv *priv = phy_get_drvdata(phy); + int ret; + + ret = clk_bulk_prepare_enable(priv->num_clks, priv->clks); + if (ret) { + pr_err("failed to enable PCIe bulk clks %d\n", ret); + return ret; + } + + reset_control_assert(priv->p30phy); + udelay(1); + + if (priv->ops->phy_init) { + ret = priv->ops->phy_init(priv); + if (ret) + clk_bulk_disable_unprepare(priv->num_clks, priv->clks); + } + + return ret; +} + +static int rochchip_p3phy_exit(struct phy *phy) +{ + struct rockchip_p3phy_priv *priv = phy_get_drvdata(phy); + + clk_bulk_disable_unprepare(priv->num_clks, priv->clks); + reset_control_assert(priv->p30phy); + return 0; +} + +static const struct phy_ops rochchip_p3phy_ops = { + .init = rochchip_p3phy_init, + .exit = rochchip_p3phy_exit, + .set_mode = rockchip_p3phy_set_mode, + .owner = THIS_MODULE, +}; + +static int rockchip_p3phy_probe(struct platform_device *pdev) +{ + struct phy_provider *phy_provider; + struct device *dev = &pdev->dev; + struct rockchip_p3phy_priv *priv; + struct device_node *np = dev->of_node; + struct resource *res; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + priv->mmio = devm_ioremap_resource(dev, res); + if (IS_ERR(priv->mmio)) { + ret = PTR_ERR(priv->mmio); + return ret; + } + + priv->ops = of_device_get_match_data(&pdev->dev); + if (!priv->ops) { + dev_err(&pdev->dev, "no of match data provided\n"); + return -EINVAL; + } + + priv->phy_grf = syscon_regmap_lookup_by_phandle(np, "rockchip,phy-grf"); + if (IS_ERR(priv->phy_grf)) { + dev_err(dev, "failed to find rockchip,phy_grf regmap\n"); + return PTR_ERR(priv->phy_grf); + } + + priv->pipe_grf = syscon_regmap_lookup_by_phandle(dev->of_node, + "rockchip,pipe-grf"); + if (IS_ERR(priv->pipe_grf)) + dev_info(dev, "failed to find rockchip,pipe_grf regmap\n"); + + priv->num_lanes = of_property_read_variable_u32_array(dev->of_node, "data-lanes", + priv->lanes, 2, + ARRAY_SIZE(priv->lanes)); + + /* if no data-lanes assume aggregation */ + if (priv->num_lanes == -EINVAL) { + dev_dbg(dev, "no data-lanes property found\n"); + priv->num_lanes = 1; + priv->lanes[0] = 1; + } else if (priv->num_lanes < 0) { + dev_err(dev, "failed to read data-lanes property %d\n", priv->num_lanes); + return priv->num_lanes; + } + + priv->phy = devm_phy_create(dev, NULL, &rochchip_p3phy_ops); + if (IS_ERR(priv->phy)) { + dev_err(dev, "failed to create combphy\n"); + return PTR_ERR(priv->phy); + } + + priv->p30phy = devm_reset_control_get_optional_exclusive(dev, "phy"); + if (IS_ERR(priv->p30phy)) { + return dev_err_probe(dev, PTR_ERR(priv->p30phy), + "failed to get phy reset control\n"); + } + if (!priv->p30phy) + dev_info(dev, "no phy reset control specified\n"); + + priv->num_clks = devm_clk_bulk_get_all(dev, &priv->clks); + if (priv->num_clks < 1) + return -ENODEV; + + dev_set_drvdata(dev, priv); + phy_set_drvdata(priv->phy, priv); + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); + return PTR_ERR_OR_ZERO(phy_provider); +} + +static const struct of_device_id rockchip_p3phy_of_match[] = { + { .compatible = "rockchip,rk3568-pcie3-phy", .data = &rk3568_ops }, + { .compatible = "rockchip,rk3588-pcie3-phy", .data = &rk3588_ops }, + { }, +}; +MODULE_DEVICE_TABLE(of, rockchip_p3phy_of_match); + +static struct platform_driver rockchip_p3phy_driver = { + .probe = rockchip_p3phy_probe, + .driver = { + .name = "rockchip-snps-pcie3-phy", + .of_match_table = rockchip_p3phy_of_match, + }, +}; +module_platform_driver(rockchip_p3phy_driver); +MODULE_DESCRIPTION("Rockchip Synopsys PCIe 3.0 PHY driver"); +MODULE_LICENSE("GPL"); diff --git a/target/linux/rockchip/files/include/linux/phy/pcie.h b/target/linux/rockchip/files/include/linux/phy/pcie.h new file mode 100644 index 000000000..93c997f52 --- /dev/null +++ b/target/linux/rockchip/files/include/linux/phy/pcie.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2021 Rockchip Electronics Co., Ltd. + */ +#ifndef __PHY_PCIE_H +#define __PHY_PCIE_H + +#define PHY_MODE_PCIE_RC 20 +#define PHY_MODE_PCIE_EP 21 +#define PHY_MODE_PCIE_BIFURCATION 22 + +#endif diff --git a/target/linux/rockchip/modules.mk b/target/linux/rockchip/modules.mk index 68380306c..107017dbd 100644 --- a/target/linux/rockchip/modules.mk +++ b/target/linux/rockchip/modules.mk @@ -16,6 +16,8 @@ define KernelPackage/drm-rockchip CONFIG_PHY_ROCKCHIP_INNO_HDMI \ CONFIG_DRM_DW_HDMI \ CONFIG_DRM_DW_HDMI_CEC \ + CONFIG_ROCKCHIP_VOP=y \ + CONFIG_ROCKCHIP_VOP2=y CONFIG_ROCKCHIP_ANALOGIX_DP=n \ CONFIG_ROCKCHIP_CDN_DP=n \ CONFIG_ROCKCHIP_DW_HDMI=y \ diff --git a/target/linux/rockchip/patches-5.15/008-0001-v5.16-ASoC-rockchip-Add-support-for-rv1126-pdm.patch b/target/linux/rockchip/patches-5.15/008-0001-v5.16-ASoC-rockchip-Add-support-for-rv1126-pdm.patch new file mode 100644 index 000000000..58d4b15cf --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0001-v5.16-ASoC-rockchip-Add-support-for-rv1126-pdm.patch @@ -0,0 +1,155 @@ +From d269aa2ab975807764dc2509e4156bb9b6bd0d34 Mon Sep 17 00:00:00 2001 +From: Sugar Zhang +Date: Fri, 3 Sep 2021 21:23:24 +0800 +Subject: [PATCH] ASoC: rockchip: Add support for rv1126 pdm + +This patch adds support for rv1126 pdm controller which +redesign cic filiter for better performance. + +Signed-off-by: Sugar Zhang +Link: https://lore.kernel.org/r/1630675410-3354-1-git-send-email-sugar.zhang@rock-chips.com +Signed-off-by: Mark Brown +--- + sound/soc/rockchip/rockchip_pdm.c | 76 ++++++++++++++++++++++++++++--- + sound/soc/rockchip/rockchip_pdm.h | 3 ++ + 2 files changed, 73 insertions(+), 6 deletions(-) + +--- a/sound/soc/rockchip/rockchip_pdm.c ++++ b/sound/soc/rockchip/rockchip_pdm.c +@@ -24,6 +24,7 @@ + enum rk_pdm_version { + RK_PDM_RK3229, + RK_PDM_RK3308, ++ RK_PDM_RV1126, + }; + + struct rk_pdm_dev { +@@ -121,6 +122,55 @@ static unsigned int get_pdm_ds_ratio(uns + return ratio; + } + ++static unsigned int get_pdm_cic_ratio(unsigned int clk) ++{ ++ switch (clk) { ++ case 4096000: ++ case 5644800: ++ case 6144000: ++ return 0; ++ case 2048000: ++ case 2822400: ++ case 3072000: ++ return 1; ++ case 1024000: ++ case 1411200: ++ case 1536000: ++ return 2; ++ default: ++ return 1; ++ } ++} ++ ++static unsigned int samplerate_to_bit(unsigned int samplerate) ++{ ++ switch (samplerate) { ++ case 8000: ++ case 11025: ++ case 12000: ++ return 0; ++ case 16000: ++ case 22050: ++ case 24000: ++ return 1; ++ case 32000: ++ return 2; ++ case 44100: ++ case 48000: ++ return 3; ++ case 64000: ++ case 88200: ++ case 96000: ++ return 4; ++ case 128000: ++ case 176400: ++ case 192000: ++ return 5; ++ default: ++ return 1; ++ } ++} ++ + static inline struct rk_pdm_dev *to_info(struct snd_soc_dai *dai) + { + return snd_soc_dai_get_drvdata(dai); +@@ -166,7 +216,8 @@ static int rockchip_pdm_hw_params(struct + if (ret) + return -EINVAL; + +- if (pdm->version == RK_PDM_RK3308) { ++ if (pdm->version == RK_PDM_RK3308 || ++ pdm->version == RK_PDM_RV1126) { + rational_best_approximation(clk_out, clk_src, + GENMASK(16 - 1, 0), + GENMASK(16 - 1, 0), +@@ -194,8 +245,18 @@ static int rockchip_pdm_hw_params(struct + PDM_CLK_FD_RATIO_MSK, + val); + } +- val = get_pdm_ds_ratio(samplerate); +- regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, PDM_DS_RATIO_MSK, val); ++ ++ if (pdm->version == RK_PDM_RV1126) { ++ val = get_pdm_cic_ratio(clk_out); ++ regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, PDM_CIC_RATIO_MSK, val); ++ val = samplerate_to_bit(samplerate); ++ regmap_update_bits(pdm->regmap, PDM_CTRL0, ++ PDM_SAMPLERATE_MSK, PDM_SAMPLERATE(val)); ++ } else { ++ val = get_pdm_ds_ratio(samplerate); ++ regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, PDM_DS_RATIO_MSK, val); ++ } ++ + regmap_update_bits(pdm->regmap, PDM_HPF_CTRL, + PDM_HPF_CF_MSK, PDM_HPF_60HZ); + regmap_update_bits(pdm->regmap, PDM_HPF_CTRL, +@@ -441,9 +502,10 @@ static bool rockchip_pdm_precious_reg(st + } + + static const struct reg_default rockchip_pdm_reg_defaults[] = { +- {0x04, 0x78000017}, +- {0x08, 0x0bb8ea60}, +- {0x18, 0x0000001f}, ++ { PDM_CTRL0, 0x78000017 }, ++ { PDM_CTRL1, 0x0bb8ea60 }, ++ { PDM_CLK_CTRL, 0x0000e401 }, ++ { PDM_DMA_CTRL, 0x0000001f }, + }; + + static const struct regmap_config rockchip_pdm_regmap_config = { +@@ -469,6 +531,8 @@ static const struct of_device_id rockchi + .data = (void *)RK_PDM_RK3308 }, + { .compatible = "rockchip,rk3308-pdm", + .data = (void *)RK_PDM_RK3308 }, ++ { .compatible = "rockchip,rv1126-pdm", ++ .data = (void *)RK_PDM_RV1126 }, + {}, + }; + MODULE_DEVICE_TABLE(of, rockchip_pdm_match); +--- a/sound/soc/rockchip/rockchip_pdm.h ++++ b/sound/soc/rockchip/rockchip_pdm.h +@@ -41,6 +41,8 @@ + #define PDM_PATH1_EN BIT(28) + #define PDM_PATH0_EN BIT(27) + #define PDM_HWT_EN BIT(26) ++#define PDM_SAMPLERATE_MSK GENMASK(7, 5) ++#define PDM_SAMPLERATE(x) ((x) << 5) + #define PDM_VDW_MSK (0x1f << 0) + #define PDM_VDW(X) ((X - 1) << 0) + +@@ -66,6 +68,7 @@ + #define PDM_CLK_1280FS (0x2 << 0) + #define PDM_CLK_2560FS (0x3 << 0) + #define PDM_CLK_5120FS (0x4 << 0) ++#define PDM_CIC_RATIO_MSK (0x3 << 0) + + /* PDM HPF CTRL */ + #define PDM_HPF_LE BIT(3) diff --git a/target/linux/rockchip/patches-5.15/008-0002-v5.16-ASoC-rockchip-pdm-Add-support-for-rk3568-pdm.patch b/target/linux/rockchip/patches-5.15/008-0002-v5.16-ASoC-rockchip-pdm-Add-support-for-rk3568-pdm.patch new file mode 100644 index 000000000..7eef2b8a7 --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0002-v5.16-ASoC-rockchip-pdm-Add-support-for-rk3568-pdm.patch @@ -0,0 +1,26 @@ +From d00d1cd4ab42f92d4d871deb9cdea1d7c262a213 Mon Sep 17 00:00:00 2001 +From: Sugar Zhang +Date: Fri, 3 Sep 2021 21:23:26 +0800 +Subject: [PATCH] ASoC: rockchip: pdm: Add support for rk3568 pdm + +This patch adds compatible for rk3568 which is the same +with rv1126. + +Signed-off-by: Sugar Zhang +Link: https://lore.kernel.org/r/1630675410-3354-3-git-send-email-sugar.zhang@rock-chips.com +Signed-off-by: Mark Brown +--- + sound/soc/rockchip/rockchip_pdm.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/sound/soc/rockchip/rockchip_pdm.c ++++ b/sound/soc/rockchip/rockchip_pdm.c +@@ -531,6 +531,8 @@ static const struct of_device_id rockchi + .data = (void *)RK_PDM_RK3308 }, + { .compatible = "rockchip,rk3308-pdm", + .data = (void *)RK_PDM_RK3308 }, ++ { .compatible = "rockchip,rk3568-pdm", ++ .data = (void *)RK_PDM_RV1126 }, + { .compatible = "rockchip,rv1126-pdm", + .data = (void *)RK_PDM_RV1126 }, + {}, diff --git a/target/linux/rockchip/patches-5.15/008-0003-v5.16-ASoC-rockchip-pdm-Add-support-for-path-map.patch b/target/linux/rockchip/patches-5.15/008-0003-v5.16-ASoC-rockchip-pdm-Add-support-for-path-map.patch new file mode 100644 index 000000000..b280723b6 --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0003-v5.16-ASoC-rockchip-pdm-Add-support-for-path-map.patch @@ -0,0 +1,95 @@ +From 13e6e042a6f9c2be676f421935e026308de3303c Mon Sep 17 00:00:00 2001 +From: Sugar Zhang +Date: Fri, 3 Sep 2021 21:23:28 +0800 +Subject: [PATCH] ASoC: rockchip: pdm: Add support for path map + +This patch adds property 'rockchip,path-map' for path mapping. + +e.g. + +"rockchip,path-map = <3 2 1 0>" means the mapping as follows: + + path0 <-- sdi3 + path1 <-- sdi2 + path2 <-- sdi1 + path3 <-- sdi0 + +Signed-off-by: Sugar Zhang +Link: https://lore.kernel.org/r/1630675410-3354-5-git-send-email-sugar.zhang@rock-chips.com +Signed-off-by: Mark Brown +--- + sound/soc/rockchip/rockchip_pdm.c | 34 +++++++++++++++++++++++++++++++ + sound/soc/rockchip/rockchip_pdm.h | 3 +++ + 2 files changed, 37 insertions(+) + +--- a/sound/soc/rockchip/rockchip_pdm.c ++++ b/sound/soc/rockchip/rockchip_pdm.c +@@ -20,6 +20,7 @@ + + #define PDM_DMA_BURST_SIZE (8) /* size * width: 8*4 = 32 bytes */ + #define PDM_SIGNOFF_CLK_RATE (100000000) ++#define PDM_PATH_MAX (4) + + enum rk_pdm_version { + RK_PDM_RK3229, +@@ -539,8 +540,36 @@ static const struct of_device_id rockchi + }; + MODULE_DEVICE_TABLE(of, rockchip_pdm_match); + ++static int rockchip_pdm_path_parse(struct rk_pdm_dev *pdm, struct device_node *node) ++{ ++ unsigned int path[PDM_PATH_MAX]; ++ int cnt = 0, ret = 0, i = 0, val = 0, msk = 0; ++ ++ cnt = of_count_phandle_with_args(node, "rockchip,path-map", ++ NULL); ++ if (cnt != PDM_PATH_MAX) ++ return cnt; ++ ++ ret = of_property_read_u32_array(node, "rockchip,path-map", ++ path, cnt); ++ if (ret) ++ return ret; ++ ++ for (i = 0; i < cnt; i++) { ++ if (path[i] >= PDM_PATH_MAX) ++ return -EINVAL; ++ msk |= PDM_PATH_MASK(i); ++ val |= PDM_PATH(i, path[i]); ++ } ++ ++ regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, msk, val); ++ ++ return 0; ++} ++ + static int rockchip_pdm_probe(struct platform_device *pdev) + { ++ struct device_node *node = pdev->dev.of_node; + const struct of_device_id *match; + struct rk_pdm_dev *pdm; + struct resource *res; +@@ -606,6 +635,11 @@ static int rockchip_pdm_probe(struct pla + } + + rockchip_pdm_rxctrl(pdm, 0); ++ ++ ret = rockchip_pdm_path_parse(pdm, node); ++ if (ret != 0 && ret != -ENOENT) ++ goto err_suspend; ++ + ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); + if (ret) { + dev_err(&pdev->dev, "could not register pcm: %d\n", ret); +--- a/sound/soc/rockchip/rockchip_pdm.h ++++ b/sound/soc/rockchip/rockchip_pdm.h +@@ -53,6 +53,9 @@ + #define PDM_FD_DENOMINATOR_MSK GENMASK(15, 0) + + /* PDM CLK CTRL */ ++#define PDM_PATH_SHIFT(x) (8 + (x) * 2) ++#define PDM_PATH_MASK(x) (0x3 << PDM_PATH_SHIFT(x)) ++#define PDM_PATH(x, v) ((v) << PDM_PATH_SHIFT(x)) + #define PDM_CLK_FD_RATIO_MSK BIT(6) + #define PDM_CLK_FD_RATIO_40 (0X0 << 6) + #define PDM_CLK_FD_RATIO_35 BIT(6) diff --git a/target/linux/rockchip/patches-5.15/008-0004-v5.16-arm64-dts-rockchip-add-rk3568-tsadc-nodes.patch b/target/linux/rockchip/patches-5.15/008-0004-v5.16-arm64-dts-rockchip-add-rk3568-tsadc-nodes.patch new file mode 100644 index 000000000..fdf559c5a --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0004-v5.16-arm64-dts-rockchip-add-rk3568-tsadc-nodes.patch @@ -0,0 +1,32 @@ +From 1330875dc2a3742fd41127e78d5036f2d8f261da Mon Sep 17 00:00:00 2001 +From: Peter Geis +Date: Wed, 28 Jul 2021 14:00:31 -0400 +Subject: [PATCH] arm64: dts: rockchip: add rk3568 tsadc nodes + +Add the thermal and tsadc nodes to the rk3568 device tree. +There are two sensors, one for the cpu, one for the gpu. + +Signed-off-by: Peter Geis +Link: https://lore.kernel.org/r/20210728180034.717953-6-pgwipeout@gmail.com +Signed-off-by: Heiko Stuebner +--- + .../boot/dts/rockchip/rk3568-pinctrl.dtsi | 9 +++ + arch/arm64/boot/dts/rockchip/rk356x.dtsi | 70 +++++++++++++++++++ + 2 files changed, 79 insertions(+) + +--- a/arch/arm64/boot/dts/rockchip/rk3568-pinctrl.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3568-pinctrl.dtsi +@@ -3108,4 +3108,13 @@ + <4 RK_PA0 3 &pcfg_pull_none_drv_level_2>; + }; + }; ++ ++ tsadc { ++ /omit-if-no-ref/ ++ tsadc_pin: tsadc-pin { ++ rockchip,pins = ++ /* tsadc_pin */ ++ <0 RK_PA1 0 &pcfg_pull_none>; ++ }; ++ }; + }; diff --git a/target/linux/rockchip/patches-5.15/008-0005-v5.16-thermal-drivers-rockchip_thermal-Allow-more-resets-for-ts.patch b/target/linux/rockchip/patches-5.15/008-0005-v5.16-thermal-drivers-rockchip_thermal-Allow-more-resets-for-ts.patch new file mode 100644 index 000000000..c63c7f020 --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0005-v5.16-thermal-drivers-rockchip_thermal-Allow-more-resets-for-ts.patch @@ -0,0 +1,28 @@ +From 02832ed8ae2c8b130efea4e43d3ecac50b4b7933 Mon Sep 17 00:00:00 2001 +From: Johan Jonker +Date: Thu, 30 Sep 2021 13:05:16 +0200 +Subject: [PATCH] thermal/drivers/rockchip_thermal: Allow more resets for tsadc + node + +The tsadc node in rk356x.dtsi has more resets then currently supported +by the rockchip_thermal.c driver, so use +devm_reset_control_array_get() to reset them all. + +Signed-off-by: Johan Jonker +Link: https://lore.kernel.org/r/20210930110517.14323-3-jbx6244@gmail.com +Signed-off-by: Daniel Lezcano +--- + drivers/thermal/rockchip_thermal.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/thermal/rockchip_thermal.c ++++ b/drivers/thermal/rockchip_thermal.c +@@ -1383,7 +1383,7 @@ static int rockchip_thermal_probe(struct + if (IS_ERR(thermal->regs)) + return PTR_ERR(thermal->regs); + +- thermal->reset = devm_reset_control_get(&pdev->dev, "tsadc-apb"); ++ thermal->reset = devm_reset_control_array_get(&pdev->dev, false, false); + if (IS_ERR(thermal->reset)) { + error = PTR_ERR(thermal->reset); + dev_err(&pdev->dev, "failed to get tsadc reset: %d\n", error); diff --git a/target/linux/rockchip/patches-5.15/008-0006-v5.17-phy-phy-rockchip-inno-usb2-support-address_cells-2.patch b/target/linux/rockchip/patches-5.15/008-0006-v5.17-phy-phy-rockchip-inno-usb2-support-address_cells-2.patch new file mode 100644 index 000000000..8ee043d5d --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0006-v5.17-phy-phy-rockchip-inno-usb2-support-address_cells-2.patch @@ -0,0 +1,45 @@ +From 9c19c531dc98d7ba49b44802a607042e763ebe21 Mon Sep 17 00:00:00 2001 +From: Peter Geis +Date: Wed, 15 Dec 2021 16:02:47 -0500 +Subject: [PATCH] phy: phy-rockchip-inno-usb2: support #address_cells = 2 + +New Rockchip devices have the usb phy nodes as standalone devices. +These nodes have register nodes with #address_cells = 2, but only use 32 +bit addresses. + +Adjust the driver to check if the returned address is "0", and adjust +the index in that case. + +Signed-off-by: Peter Geis +Tested-by: Michael Riesch +Link: https://lore.kernel.org/r/20211215210252.120923-4-pgwipeout@gmail.com +Signed-off-by: Vinod Koul +--- + drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +@@ -1098,12 +1098,21 @@ static int rockchip_usb2phy_probe(struct + rphy->usbgrf = NULL; + } + +- if (of_property_read_u32(np, "reg", ®)) { ++ if (of_property_read_u32_index(np, "reg", 0, ®)) { + dev_err(dev, "the reg property is not assigned in %pOFn node\n", + np); + return -EINVAL; + } + ++ /* support address_cells=2 */ ++ if (reg == 0) { ++ if (of_property_read_u32_index(np, "reg", 1, ®)) { ++ dev_err(dev, "the reg property is not assigned in %pOFn node\n", ++ np); ++ return -EINVAL; ++ } ++ } ++ + rphy->dev = dev; + phy_cfgs = match->data; + rphy->chg_state = USB_CHG_STATE_UNDEFINED; diff --git a/target/linux/rockchip/patches-5.15/008-0007-v5.17-phy-phy-rockchip-inno-usb2-support-muxed-interrupts.patch b/target/linux/rockchip/patches-5.15/008-0007-v5.17-phy-phy-rockchip-inno-usb2-support-muxed-interrupts.patch new file mode 100644 index 000000000..13614e9ae --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0007-v5.17-phy-phy-rockchip-inno-usb2-support-muxed-interrupts.patch @@ -0,0 +1,237 @@ +From ed2b5a8e6b98d042b323afbe177a5dc618921b31 Mon Sep 17 00:00:00 2001 +From: Peter Geis +Date: Wed, 15 Dec 2021 16:02:49 -0500 +Subject: [PATCH] phy: phy-rockchip-inno-usb2: support muxed interrupts + +The rk3568 usb2phy has a single muxed interrupt that handles all +interrupts. +Allow the driver to plug in only a single interrupt as necessary. + +Signed-off-by: Peter Geis +Tested-by: Michael Riesch +Link: https://lore.kernel.org/r/20211215210252.120923-6-pgwipeout@gmail.com +Signed-off-by: Vinod Koul +--- + drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 168 +++++++++++++----- + 1 file changed, 119 insertions(+), 49 deletions(-) + +--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +@@ -204,6 +204,7 @@ struct rockchip_usb2phy_port { + * @dcd_retries: The retry count used to track Data contact + * detection process. + * @edev: extcon device for notification registration ++ * @irq: muxed interrupt for single irq configuration + * @phy_cfg: phy register configuration, assigned by driver data. + * @ports: phy port instance. + */ +@@ -218,6 +219,7 @@ struct rockchip_usb2phy { + enum power_supply_type chg_type; + u8 dcd_retries; + struct extcon_dev *edev; ++ int irq; + const struct rockchip_usb2phy_cfg *phy_cfg; + struct rockchip_usb2phy_port ports[USB2PHY_NUM_PORTS]; + }; +@@ -934,6 +936,102 @@ static irqreturn_t rockchip_usb2phy_otg_ + return IRQ_NONE; + } + ++static irqreturn_t rockchip_usb2phy_irq(int irq, void *data) ++{ ++ struct rockchip_usb2phy *rphy = data; ++ struct rockchip_usb2phy_port *rport; ++ irqreturn_t ret = IRQ_NONE; ++ unsigned int index; ++ ++ for (index = 0; index < rphy->phy_cfg->num_ports; index++) { ++ rport = &rphy->ports[index]; ++ if (!rport->phy) ++ continue; ++ ++ /* Handle linestate irq for both otg port and host port */ ++ ret = rockchip_usb2phy_linestate_irq(irq, rport); ++ } ++ ++ return ret; ++} ++ ++static int rockchip_usb2phy_port_irq_init(struct rockchip_usb2phy *rphy, ++ struct rockchip_usb2phy_port *rport, ++ struct device_node *child_np) ++{ ++ int ret; ++ ++ /* ++ * If the usb2 phy used combined irq for otg and host port, ++ * don't need to init otg and host port irq separately. ++ */ ++ if (rphy->irq > 0) ++ return 0; ++ ++ switch (rport->port_id) { ++ case USB2PHY_PORT_HOST: ++ rport->ls_irq = of_irq_get_byname(child_np, "linestate"); ++ if (rport->ls_irq < 0) { ++ dev_err(rphy->dev, "no linestate irq provided\n"); ++ return rport->ls_irq; ++ } ++ ++ ret = devm_request_threaded_irq(rphy->dev, rport->ls_irq, NULL, ++ rockchip_usb2phy_linestate_irq, ++ IRQF_ONESHOT, ++ "rockchip_usb2phy", rport); ++ if (ret) { ++ dev_err(rphy->dev, "failed to request linestate irq handle\n"); ++ return ret; ++ } ++ break; ++ case USB2PHY_PORT_OTG: ++ /* ++ * Some SoCs use one interrupt with otg-id/otg-bvalid/linestate ++ * interrupts muxed together, so probe the otg-mux interrupt first, ++ * if not found, then look for the regular interrupts one by one. ++ */ ++ rport->otg_mux_irq = of_irq_get_byname(child_np, "otg-mux"); ++ if (rport->otg_mux_irq > 0) { ++ ret = devm_request_threaded_irq(rphy->dev, rport->otg_mux_irq, ++ NULL, ++ rockchip_usb2phy_otg_mux_irq, ++ IRQF_ONESHOT, ++ "rockchip_usb2phy_otg", ++ rport); ++ if (ret) { ++ dev_err(rphy->dev, ++ "failed to request otg-mux irq handle\n"); ++ return ret; ++ } ++ } else { ++ rport->bvalid_irq = of_irq_get_byname(child_np, "otg-bvalid"); ++ if (rport->bvalid_irq < 0) { ++ dev_err(rphy->dev, "no vbus valid irq provided\n"); ++ ret = rport->bvalid_irq; ++ return ret; ++ } ++ ++ ret = devm_request_threaded_irq(rphy->dev, rport->bvalid_irq, ++ NULL, ++ rockchip_usb2phy_bvalid_irq, ++ IRQF_ONESHOT, ++ "rockchip_usb2phy_bvalid", ++ rport); ++ if (ret) { ++ dev_err(rphy->dev, ++ "failed to request otg-bvalid irq handle\n"); ++ return ret; ++ } ++ } ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ + static int rockchip_usb2phy_host_port_init(struct rockchip_usb2phy *rphy, + struct rockchip_usb2phy_port *rport, + struct device_node *child_np) +@@ -947,18 +1045,9 @@ static int rockchip_usb2phy_host_port_in + mutex_init(&rport->mutex); + INIT_DELAYED_WORK(&rport->sm_work, rockchip_usb2phy_sm_work); + +- rport->ls_irq = of_irq_get_byname(child_np, "linestate"); +- if (rport->ls_irq < 0) { +- dev_err(rphy->dev, "no linestate irq provided\n"); +- return rport->ls_irq; +- } +- +- ret = devm_request_threaded_irq(rphy->dev, rport->ls_irq, NULL, +- rockchip_usb2phy_linestate_irq, +- IRQF_ONESHOT, +- "rockchip_usb2phy", rport); ++ ret = rockchip_usb2phy_port_irq_init(rphy, rport, child_np); + if (ret) { +- dev_err(rphy->dev, "failed to request linestate irq handle\n"); ++ dev_err(rphy->dev, "failed to setup host irq\n"); + return ret; + } + +@@ -1007,44 +1096,10 @@ static int rockchip_usb2phy_otg_port_ini + INIT_DELAYED_WORK(&rport->chg_work, rockchip_chg_detect_work); + INIT_DELAYED_WORK(&rport->otg_sm_work, rockchip_usb2phy_otg_sm_work); + +- /* +- * Some SoCs use one interrupt with otg-id/otg-bvalid/linestate +- * interrupts muxed together, so probe the otg-mux interrupt first, +- * if not found, then look for the regular interrupts one by one. +- */ +- rport->otg_mux_irq = of_irq_get_byname(child_np, "otg-mux"); +- if (rport->otg_mux_irq > 0) { +- ret = devm_request_threaded_irq(rphy->dev, rport->otg_mux_irq, +- NULL, +- rockchip_usb2phy_otg_mux_irq, +- IRQF_ONESHOT, +- "rockchip_usb2phy_otg", +- rport); +- if (ret) { +- dev_err(rphy->dev, +- "failed to request otg-mux irq handle\n"); +- goto out; +- } +- } else { +- rport->bvalid_irq = of_irq_get_byname(child_np, "otg-bvalid"); +- if (rport->bvalid_irq < 0) { +- dev_err(rphy->dev, "no vbus valid irq provided\n"); +- ret = rport->bvalid_irq; +- goto out; +- } +- +- ret = devm_request_threaded_irq(rphy->dev, rport->bvalid_irq, +- NULL, +- rockchip_usb2phy_bvalid_irq, +- IRQF_ONESHOT, +- "rockchip_usb2phy_bvalid", +- rport); +- if (ret) { +- dev_err(rphy->dev, +- "failed to request otg-bvalid irq handle\n"); +- goto out; +- } +- } ++ ret = rockchip_usb2phy_port_irq_init(rphy, rport, child_np); ++ if (ret) { ++ dev_err(rphy->dev, "failed to init irq for host port\n"); ++ goto out; + + if (!IS_ERR(rphy->edev)) { + rport->event_nb.notifier_call = rockchip_otg_event; +@@ -1117,6 +1172,7 @@ static int rockchip_usb2phy_probe(struct + phy_cfgs = match->data; + rphy->chg_state = USB_CHG_STATE_UNDEFINED; + rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN; ++ rphy->irq = platform_get_irq_optional(pdev, 0); + platform_set_drvdata(pdev, rphy); + + ret = rockchip_usb2phy_extcon_register(rphy); +@@ -1196,6 +1252,20 @@ next_child: + } + + provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); ++ ++ if (rphy->irq > 0) { ++ ret = devm_request_threaded_irq(rphy->dev, rphy->irq, NULL, ++ rockchip_usb2phy_irq, ++ IRQF_ONESHOT, ++ "rockchip_usb2phy", ++ rphy); ++ if (ret) { ++ dev_err(rphy->dev, ++ "failed to request usb2phy irq handle\n"); ++ goto put_child; ++ } ++ } ++ + return PTR_ERR_OR_ZERO(provider); + + put_child: diff --git a/target/linux/rockchip/patches-5.15/008-0008-v5.17-phy-phy-rockchip-inno-usb2-support-standalone-phy-nodes.patch b/target/linux/rockchip/patches-5.15/008-0008-v5.17-phy-phy-rockchip-inno-usb2-support-standalone-phy-nodes.patch new file mode 100644 index 000000000..4a6f282c6 --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0008-v5.17-phy-phy-rockchip-inno-usb2-support-standalone-phy-nodes.patch @@ -0,0 +1,44 @@ +From e6915e1acca57bc4fdb61dccd5cc2e49f72ef743 Mon Sep 17 00:00:00 2001 +From: Peter Geis +Date: Wed, 15 Dec 2021 16:02:48 -0500 +Subject: [PATCH] phy: phy-rockchip-inno-usb2: support standalone phy nodes + +New Rockchip devices have the usb2 phy devices as standalone nodes +instead of children of the grf node. +Allow the driver to find the grf node from a phandle. + +Signed-off-by: Peter Geis +Tested-by: Michael Riesch +Link: https://lore.kernel.org/r/20211215210252.120923-5-pgwipeout@gmail.com +Signed-off-by: Vinod Koul +--- + drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 17 ++++++++++++----- + 1 file changed, 12 insertions(+), 5 deletions(-) + +--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +@@ -1136,12 +1136,19 @@ static int rockchip_usb2phy_probe(struct + return -EINVAL; + } + +- if (!dev->parent || !dev->parent->of_node) +- return -EINVAL; ++ if (!dev->parent || !dev->parent->of_node) { ++ rphy->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,usbgrf"); ++ if (IS_ERR(rphy->grf)) { ++ dev_err(dev, "failed to locate usbgrf\n"); ++ return PTR_ERR(rphy->grf); ++ } ++ } + +- rphy->grf = syscon_node_to_regmap(dev->parent->of_node); +- if (IS_ERR(rphy->grf)) +- return PTR_ERR(rphy->grf); ++ else { ++ rphy->grf = syscon_node_to_regmap(dev->parent->of_node); ++ if (IS_ERR(rphy->grf)) ++ return PTR_ERR(rphy->grf); ++ } + + if (of_device_is_compatible(np, "rockchip,rv1108-usb2phy")) { + rphy->usbgrf = diff --git a/target/linux/rockchip/patches-5.15/008-0009-v5.17-phy-phy-rockchip-inno-usb2-add-rk3568-support.patch b/target/linux/rockchip/patches-5.15/008-0009-v5.17-phy-phy-rockchip-inno-usb2-add-rk3568-support.patch new file mode 100644 index 000000000..8de87e138 --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0009-v5.17-phy-phy-rockchip-inno-usb2-add-rk3568-support.patch @@ -0,0 +1,104 @@ +From 42b559727a45d79c811f493515eb9b7e56016421 Mon Sep 17 00:00:00 2001 +From: Peter Geis +Date: Wed, 15 Dec 2021 16:02:50 -0500 +Subject: [PATCH] phy: phy-rockchip-inno-usb2: add rk3568 support + +The rk3568 usb2phy is a standalone device with a single muxed interrupt. +Add support for the registers to the usb2phy driver. + +Signed-off-by: Peter Geis +Tested-by: Michael Riesch +Link: https://lore.kernel.org/r/20211215210252.120923-7-pgwipeout@gmail.com +Signed-off-by: Vinod Koul +--- + drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 65 +++++++++++++++++++ + 1 file changed, 65 insertions(+) + +--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +@@ -1100,6 +1100,7 @@ static int rockchip_usb2phy_otg_port_ini + if (ret) { + dev_err(rphy->dev, "failed to init irq for host port\n"); + goto out; ++ } + + if (!IS_ERR(rphy->edev)) { + rport->event_nb.notifier_call = rockchip_otg_event; +@@ -1511,6 +1512,69 @@ static const struct rockchip_usb2phy_cfg + { /* sentinel */ } + }; + ++static const struct rockchip_usb2phy_cfg rk3568_phy_cfgs[] = { ++ { ++ .reg = 0xfe8a0000, ++ .num_ports = 2, ++ .clkout_ctl = { 0x0008, 4, 4, 1, 0 }, ++ .port_cfgs = { ++ [USB2PHY_PORT_OTG] = { ++ .phy_sus = { 0x0000, 8, 0, 0, 0x1d1 }, ++ .bvalid_det_en = { 0x0080, 2, 2, 0, 1 }, ++ .bvalid_det_st = { 0x0084, 2, 2, 0, 1 }, ++ .bvalid_det_clr = { 0x0088, 2, 2, 0, 1 }, ++ .utmi_avalid = { 0x00c0, 10, 10, 0, 1 }, ++ .utmi_bvalid = { 0x00c0, 9, 9, 0, 1 }, ++ }, ++ [USB2PHY_PORT_HOST] = { ++ /* Select suspend control from controller */ ++ .phy_sus = { 0x0004, 8, 0, 0x1d2, 0x1d2 }, ++ .ls_det_en = { 0x0080, 1, 1, 0, 1 }, ++ .ls_det_st = { 0x0084, 1, 1, 0, 1 }, ++ .ls_det_clr = { 0x0088, 1, 1, 0, 1 }, ++ .utmi_ls = { 0x00c0, 17, 16, 0, 1 }, ++ .utmi_hstdet = { 0x00c0, 19, 19, 0, 1 } ++ } ++ }, ++ .chg_det = { ++ .opmode = { 0x0000, 3, 0, 5, 1 }, ++ .cp_det = { 0x00c0, 24, 24, 0, 1 }, ++ .dcp_det = { 0x00c0, 23, 23, 0, 1 }, ++ .dp_det = { 0x00c0, 25, 25, 0, 1 }, ++ .idm_sink_en = { 0x0008, 8, 8, 0, 1 }, ++ .idp_sink_en = { 0x0008, 7, 7, 0, 1 }, ++ .idp_src_en = { 0x0008, 9, 9, 0, 1 }, ++ .rdm_pdwn_en = { 0x0008, 10, 10, 0, 1 }, ++ .vdm_src_en = { 0x0008, 12, 12, 0, 1 }, ++ .vdp_src_en = { 0x0008, 11, 11, 0, 1 }, ++ }, ++ }, ++ { ++ .reg = 0xfe8b0000, ++ .num_ports = 2, ++ .clkout_ctl = { 0x0008, 4, 4, 1, 0 }, ++ .port_cfgs = { ++ [USB2PHY_PORT_OTG] = { ++ .phy_sus = { 0x0000, 8, 0, 0x1d2, 0x1d1 }, ++ .ls_det_en = { 0x0080, 0, 0, 0, 1 }, ++ .ls_det_st = { 0x0084, 0, 0, 0, 1 }, ++ .ls_det_clr = { 0x0088, 0, 0, 0, 1 }, ++ .utmi_ls = { 0x00c0, 5, 4, 0, 1 }, ++ .utmi_hstdet = { 0x00c0, 7, 7, 0, 1 } ++ }, ++ [USB2PHY_PORT_HOST] = { ++ .phy_sus = { 0x0004, 8, 0, 0x1d2, 0x1d1 }, ++ .ls_det_en = { 0x0080, 1, 1, 0, 1 }, ++ .ls_det_st = { 0x0084, 1, 1, 0, 1 }, ++ .ls_det_clr = { 0x0088, 1, 1, 0, 1 }, ++ .utmi_ls = { 0x00c0, 17, 16, 0, 1 }, ++ .utmi_hstdet = { 0x00c0, 19, 19, 0, 1 } ++ } ++ }, ++ }, ++ { /* sentinel */ } ++}; ++ + static const struct rockchip_usb2phy_cfg rv1108_phy_cfgs[] = { + { + .reg = 0x100, +@@ -1560,6 +1624,7 @@ static const struct of_device_id rockchi + { .compatible = "rockchip,rk3328-usb2phy", .data = &rk3328_phy_cfgs }, + { .compatible = "rockchip,rk3366-usb2phy", .data = &rk3366_phy_cfgs }, + { .compatible = "rockchip,rk3399-usb2phy", .data = &rk3399_phy_cfgs }, ++ { .compatible = "rockchip,rk3568-usb2phy", .data = &rk3568_phy_cfgs }, + { .compatible = "rockchip,rv1108-usb2phy", .data = &rv1108_phy_cfgs }, + {} + }; diff --git a/target/linux/rockchip/patches-5.15/008-0010-v5.18-clk-rockchip-Add-more-PLL-rates-for-rk3568.patch b/target/linux/rockchip/patches-5.15/008-0010-v5.18-clk-rockchip-Add-more-PLL-rates-for-rk3568.patch new file mode 100644 index 000000000..93323ff6b --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0010-v5.18-clk-rockchip-Add-more-PLL-rates-for-rk3568.patch @@ -0,0 +1,44 @@ +From 842f4cb7263953020f4e2f2f0005fc3e6fc56144 Mon Sep 17 00:00:00 2001 +From: Sascha Hauer +Date: Wed, 26 Jan 2022 15:55:33 +0100 +Subject: [PATCH] clk: rockchip: Add more PLL rates for rk3568 + +This adds a few more PLL settings needed for some standard resolutions: + +297MHz 3840x2160-30.00 +241.5MHz 2560x1440-59.95 +135MHz 1280x1024-75.02 +119MHz 1680x1050-59.88 +108MHz 1280x1024-60.02 + 78.75MHz 1024x768-75.03 + +Changes since v3: +- new patch + +Signed-off-by: Sascha Hauer +Link: https://lore.kernel.org/r/20220126145549.617165-12-s.hauer@pengutronix.de +Signed-off-by: Heiko Stuebner +--- + drivers/clk/rockchip/clk-rk3568.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/clk/rockchip/clk-rk3568.c ++++ b/drivers/clk/rockchip/clk-rk3568.c +@@ -71,11 +71,17 @@ static struct rockchip_pll_rate_table rk + RK3036_PLL_RATE(500000000, 1, 125, 6, 1, 1, 0), + RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0), + RK3036_PLL_RATE(312000000, 1, 78, 6, 1, 1, 0), ++ RK3036_PLL_RATE(297000000, 2, 99, 4, 1, 1, 0), ++ RK3036_PLL_RATE(241500000, 2, 161, 4, 2, 1, 0), + RK3036_PLL_RATE(216000000, 1, 72, 4, 2, 1, 0), + RK3036_PLL_RATE(200000000, 1, 100, 3, 4, 1, 0), + RK3036_PLL_RATE(148500000, 1, 99, 4, 4, 1, 0), ++ RK3036_PLL_RATE(135000000, 2, 45, 4, 1, 1, 0), ++ RK3036_PLL_RATE(119000000, 3, 119, 4, 2, 1, 0), ++ RK3036_PLL_RATE(108000000, 2, 45, 5, 1, 1, 0), + RK3036_PLL_RATE(100000000, 1, 150, 6, 6, 1, 0), + RK3036_PLL_RATE(96000000, 1, 96, 6, 4, 1, 0), ++ RK3036_PLL_RATE(78750000, 1, 96, 6, 4, 1, 0), + RK3036_PLL_RATE(74250000, 2, 99, 4, 4, 1, 0), + { /* sentinel */ }, + }; diff --git a/target/linux/rockchip/patches-5.15/008-0011-v5.18-clk-rockchip-Add-CLK_SET_RATE_PARENT-to-the-HDMI-referenc.patch b/target/linux/rockchip/patches-5.15/008-0011-v5.18-clk-rockchip-Add-CLK_SET_RATE_PARENT-to-the-HDMI-referenc.patch new file mode 100644 index 000000000..890fe0897 --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0011-v5.18-clk-rockchip-Add-CLK_SET_RATE_PARENT-to-the-HDMI-referenc.patch @@ -0,0 +1,52 @@ +From 6e69052f01d9131388cfcfaee929120118a267f4 Mon Sep 17 00:00:00 2001 +From: Sascha Hauer +Date: Wed, 26 Jan 2022 15:55:47 +0100 +Subject: [PATCH] clk: rockchip: Add CLK_SET_RATE_PARENT to the HDMI reference + clock on rk3568 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +On the rk3568 we have this (simplified) situation: + + .--------. .-----. .---------. +-| hpll |--.--| /n |----|dclk_vop0|- + `--------´ | `-----´ `---------´ + | .-----. .---------. + `--| /m |----|dclk_vop1|- + | `-----´ `---------´ + | .---------. + `-------------|hdmi_ref |- + `---------´ + +For the HDMI to work the HDMI reference clock needs to be the same as the +pixel clock which means the dividers have be set to one. The last patch removed +the CLK_SET_RATE_PARENT flag from the pixel clocks which means the hpll is not +changed on pixel clock changes. In order to allow the HDMI controller to +set a suitable PLL rate we now add the CLK_SET_RATE_PARENT flag to the +HDMI reference clock. With this the flow becomes: + +1) HDMI controller driver sets the rate to its pixel clock which means + hpll is set to the pixel clock +2) VOP2 driver sets dclk_vop[012] to the pixel clock. As this can't change + the hpll clock anymore this means only the divider is adjusted to the + desired value of dividing by one. + +Signed-off-by: Sascha Hauer +Link: https://lore.kernel.org/r/20220126145549.617165-26-s.hauer@pengutronix.de +Signed-off-by: Heiko Stuebner +--- + drivers/clk/rockchip/clk-rk3568.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/clk/rockchip/clk-rk3568.c ++++ b/drivers/clk/rockchip/clk-rk3568.c +@@ -1568,7 +1568,7 @@ static struct rockchip_clk_branch rk3568 + RK3568_PMU_CLKGATE_CON(2), 14, GFLAGS), + GATE(XIN_OSC0_EDPPHY_G, "xin_osc0_edpphy_g", "xin24m", 0, + RK3568_PMU_CLKGATE_CON(2), 15, GFLAGS), +- MUX(CLK_HDMI_REF, "clk_hdmi_ref", clk_hdmi_ref_p, 0, ++ MUX(CLK_HDMI_REF, "clk_hdmi_ref", clk_hdmi_ref_p, CLK_SET_RATE_PARENT, + RK3568_PMU_CLKSEL_CON(8), 7, 1, MFLAGS), + }; + diff --git a/target/linux/rockchip/patches-5.15/008-0012-v5.18-mmc-dw_mmc-Support-setting-f_min-from-host-drivers.patch b/target/linux/rockchip/patches-5.15/008-0012-v5.18-mmc-dw_mmc-Support-setting-f_min-from-host-drivers.patch new file mode 100644 index 000000000..6588068cf --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0012-v5.18-mmc-dw_mmc-Support-setting-f_min-from-host-drivers.patch @@ -0,0 +1,54 @@ +From c4313e75001492f8a288d3ffd595544cbc880821 Mon Sep 17 00:00:00 2001 +From: Peter Geis +Date: Sat, 5 Mar 2022 16:58:34 -0500 +Subject: [PATCH] mmc: dw_mmc: Support setting f_min from host drivers + +Host drivers may not be able to support frequencies as low as dw-mmc +supports. Unfortunately f_min isn't available when the drv_data->init +function is called, as the mmc_host struct hasn't been set up yet. + +Support the host drivers saving the requested minimum frequency, so we +can later set f_min when it is available. + +Signed-off-by: Peter Geis +Link: https://lore.kernel.org/r/20220305215835.2210388-2-pgwipeout@gmail.com +Signed-off-by: Ulf Hansson +--- + drivers/mmc/host/dw_mmc.c | 7 ++++++- + drivers/mmc/host/dw_mmc.h | 2 ++ + 2 files changed, 8 insertions(+), 1 deletion(-) + +--- a/drivers/mmc/host/dw_mmc.c ++++ b/drivers/mmc/host/dw_mmc.c +@@ -2853,7 +2853,12 @@ static int dw_mci_init_slot_caps(struct + if (host->pdata->caps2) + mmc->caps2 = host->pdata->caps2; + +- mmc->f_min = DW_MCI_FREQ_MIN; ++ /* if host has set a minimum_freq, we should respect it */ ++ if (host->minimum_speed) ++ mmc->f_min = host->minimum_speed; ++ else ++ mmc->f_min = DW_MCI_FREQ_MIN; ++ + if (!mmc->f_max) + mmc->f_max = DW_MCI_FREQ_MAX; + +--- a/drivers/mmc/host/dw_mmc.h ++++ b/drivers/mmc/host/dw_mmc.h +@@ -99,6 +99,7 @@ struct dw_mci_dma_slave { + * @bus_hz: The rate of @mck in Hz. This forms the basis for MMC bus + * rate and timeout calculations. + * @current_speed: Configured rate of the controller. ++ * @minimum_speed: Stored minimum rate of the controller. + * @fifoth_val: The value of FIFOTH register. + * @verid: Denote Version ID. + * @dev: Device associated with the MMC controller. +@@ -200,6 +201,7 @@ struct dw_mci { + + u32 bus_hz; + u32 current_speed; ++ u32 minimum_speed; + u32 fifoth_val; + u16 verid; + struct device *dev; diff --git a/target/linux/rockchip/patches-5.15/008-0012-v5.18-phy-rockchip-add-naneng-combo-phy-for-RK3568.patch b/target/linux/rockchip/patches-5.15/008-0012-v5.18-phy-rockchip-add-naneng-combo-phy-for-RK3568.patch new file mode 100644 index 000000000..f4ae6cb7b --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0012-v5.18-phy-rockchip-add-naneng-combo-phy-for-RK3568.patch @@ -0,0 +1,49 @@ +From 7160820d742a16313f7802e33c2956c19548e488 Mon Sep 17 00:00:00 2001 +From: Yifeng Zhao +Date: Tue, 8 Feb 2022 17:13:25 +0800 +Subject: [PATCH] phy: rockchip: add naneng combo phy for RK3568 + +This patch implements a combo phy driver for Rockchip SoCs +with NaNeng IP block. This phy can be used as pcie-phy, usb3-phy, +sata-phy or sgmii-phy. + +Signed-off-by: Yifeng Zhao +Signed-off-by: Johan Jonker +Tested-by: Peter Geis +Tested-by: Frank Wunderlich +Link: https://lore.kernel.org/r/20220208091326.12495-4-yifeng.zhao@rock-chips.com +Signed-off-by: Vinod Koul +--- + drivers/phy/rockchip/Kconfig | 8 + + drivers/phy/rockchip/Makefile | 1 + + .../rockchip/phy-rockchip-naneng-combphy.c | 581 ++++++++++++++++++ + 3 files changed, 590 insertions(+) + create mode 100644 drivers/phy/rockchip/phy-rockchip-naneng-combphy.c + +--- a/drivers/phy/rockchip/Kconfig ++++ b/drivers/phy/rockchip/Kconfig +@@ -66,6 +66,14 @@ config PHY_ROCKCHIP_INNO_DSIDPHY + Enable this to support the Rockchip MIPI/LVDS/TTL PHY with + Innosilicon IP block. + ++config PHY_ROCKCHIP_NANENG_COMBO_PHY ++ tristate "Rockchip NANENG COMBO PHY Driver" ++ depends on ARCH_ROCKCHIP && OF ++ select GENERIC_PHY ++ help ++ Enable this to support the Rockchip PCIe/USB3.0/SATA/QSGMII ++ combo PHY with NaNeng IP block. ++ + config PHY_ROCKCHIP_PCIE + tristate "Rockchip PCIe PHY Driver" + depends on (ARCH_ROCKCHIP && OF) || COMPILE_TEST +--- a/drivers/phy/rockchip/Makefile ++++ b/drivers/phy/rockchip/Makefile +@@ -6,6 +6,7 @@ obj-$(CONFIG_PHY_ROCKCHIP_INNO_CSIDPHY) + obj-$(CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY) += phy-rockchip-inno-dsidphy.o + obj-$(CONFIG_PHY_ROCKCHIP_INNO_HDMI) += phy-rockchip-inno-hdmi.o + obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2) += phy-rockchip-inno-usb2.o ++obj-$(CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY) += phy-rockchip-naneng-combphy.o + obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-rockchip-pcie.o + obj-$(CONFIG_PHY_ROCKCHIP_TYPEC) += phy-rockchip-typec.o + obj-$(CONFIG_PHY_ROCKCHIP_USB) += phy-rockchip-usb.o diff --git a/target/linux/rockchip/patches-5.15/008-0014-v5.18-mmc-dw-mmc-rockchip-Fix-handling-invalid-clock-rates.patch b/target/linux/rockchip/patches-5.15/008-0014-v5.18-mmc-dw-mmc-rockchip-Fix-handling-invalid-clock-rates.patch new file mode 100644 index 000000000..f86a6cdf0 --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0014-v5.18-mmc-dw-mmc-rockchip-Fix-handling-invalid-clock-rates.patch @@ -0,0 +1,79 @@ +From 52c92286b71e28d88642a4a416f40fbdb6cbb46f Mon Sep 17 00:00:00 2001 +From: Peter Geis +Date: Sat, 5 Mar 2022 16:58:35 -0500 +Subject: [PATCH] mmc: dw-mmc-rockchip: Fix handling invalid clock rates + +The Rockchip rk356x ciu clock cannot be set as low as the dw-mmc +hardware supports. This leads to a situation during card initialization +where the clock is set lower than the clock driver can support. The +dw-mmc-rockchip driver spews errors when this happens. +For normal operation this only happens a few times during boot, but when +cd-broken is enabled (in cases such as the SoQuartz module) this fires +multiple times each poll cycle. + +Fix this by testing the lowest possible frequency that the clock driver +can support which is within the mmc specification. Divide that rate by +the internal divider and set f_min to this. + +Signed-off-by: Peter Geis +Link: https://lore.kernel.org/r/20220305215835.2210388-3-pgwipeout@gmail.com +Signed-off-by: Ulf Hansson +--- + drivers/mmc/host/dw_mmc-rockchip.c | 27 +++++++++++++++++++++++---- + 1 file changed, 23 insertions(+), 4 deletions(-) + +--- a/drivers/mmc/host/dw_mmc-rockchip.c ++++ b/drivers/mmc/host/dw_mmc-rockchip.c +@@ -15,7 +15,9 @@ + #include "dw_mmc.h" + #include "dw_mmc-pltfm.h" + +-#define RK3288_CLKGEN_DIV 2 ++#define RK3288_CLKGEN_DIV 2 ++ ++static const unsigned int freqs[] = { 100000, 200000, 300000, 400000 }; + + struct dw_mci_rockchip_priv_data { + struct clk *drv_clk; +@@ -51,7 +53,7 @@ static void dw_mci_rk3288_set_ios(struct + + ret = clk_set_rate(host->ciu_clk, cclkin); + if (ret) +- dev_warn(host->dev, "failed to set rate %uHz\n", ios->clock); ++ dev_warn(host->dev, "failed to set rate %uHz err: %d\n", cclkin, ret); + + bus_hz = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV; + if (bus_hz != host->bus_hz) { +@@ -290,13 +292,30 @@ static int dw_mci_rk3288_parse_dt(struct + + static int dw_mci_rockchip_init(struct dw_mci *host) + { ++ int ret, i; ++ + /* It is slot 8 on Rockchip SoCs */ + host->sdio_id0 = 8; + +- if (of_device_is_compatible(host->dev->of_node, +- "rockchip,rk3288-dw-mshc")) ++ if (of_device_is_compatible(host->dev->of_node, "rockchip,rk3288-dw-mshc")) { + host->bus_hz /= RK3288_CLKGEN_DIV; + ++ /* clock driver will fail if the clock is less than the lowest source clock ++ * divided by the internal clock divider. Test for the lowest available ++ * clock and set the minimum freq to clock / clock divider. ++ */ ++ ++ for (i = 0; i < ARRAY_SIZE(freqs); i++) { ++ ret = clk_round_rate(host->ciu_clk, freqs[i] * RK3288_CLKGEN_DIV); ++ if (ret > 0) { ++ host->minimum_speed = ret / RK3288_CLKGEN_DIV; ++ break; ++ } ++ } ++ if (ret < 0) ++ dev_warn(host->dev, "no valid minimum freq: %d\n", ret); ++ } ++ + return 0; + } + diff --git a/target/linux/rockchip/patches-5.15/008-0015-v5.19-soc-rockchip-set-dwc3-clock-for-rk3566.patch b/target/linux/rockchip/patches-5.15/008-0015-v5.19-soc-rockchip-set-dwc3-clock-for-rk3566.patch new file mode 100644 index 000000000..f2288c752 --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0015-v5.19-soc-rockchip-set-dwc3-clock-for-rk3566.patch @@ -0,0 +1,51 @@ +From 5c0bb71138770d85ea840acd379edc6471b867ee Mon Sep 17 00:00:00 2001 +From: Peter Geis +Date: Fri, 8 Apr 2022 11:12:34 -0400 +Subject: [PATCH] soc: rockchip: set dwc3 clock for rk3566 + +The rk3566 dwc3 otg port clock is unavailable at boot, as it defaults to +the combophy as the clock source. As combophy0 doesn't exist on rk3566, +we need to set the clock source to the usb2 phy instead. + +Add handling to the grf driver to handle this on boot. + +Signed-off-by: Peter Geis +Link: https://lore.kernel.org/r/20220408151237.3165046-3-pgwipeout@gmail.com +Signed-off-by: Heiko Stuebner +--- + drivers/soc/rockchip/grf.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +--- a/drivers/soc/rockchip/grf.c ++++ b/drivers/soc/rockchip/grf.c +@@ -108,6 +108,20 @@ static const struct rockchip_grf_info rk + .num_values = ARRAY_SIZE(rk3399_defaults), + }; + ++#define RK3566_GRF_USB3OTG0_CON1 0x0104 ++ ++static const struct rockchip_grf_value rk3566_defaults[] __initconst = { ++ { "usb3otg port switch", RK3566_GRF_USB3OTG0_CON1, HIWORD_UPDATE(0, 1, 12) }, ++ { "usb3otg clock switch", RK3566_GRF_USB3OTG0_CON1, HIWORD_UPDATE(1, 1, 7) }, ++ { "usb3otg disable usb3", RK3566_GRF_USB3OTG0_CON1, HIWORD_UPDATE(1, 1, 0) }, ++}; ++ ++static const struct rockchip_grf_info rk3566_pipegrf __initconst = { ++ .values = rk3566_defaults, ++ .num_values = ARRAY_SIZE(rk3566_defaults), ++}; ++ ++ + static const struct of_device_id rockchip_grf_dt_match[] __initconst = { + { + .compatible = "rockchip,rk3036-grf", +@@ -130,6 +144,9 @@ static const struct of_device_id rockchi + }, { + .compatible = "rockchip,rk3399-grf", + .data = (void *)&rk3399_grf, ++ }, { ++ .compatible = "rockchip,rk3566-pipe-grf", ++ .data = (void *)&rk3566_pipegrf, + }, + { /* sentinel */ }, + }; diff --git a/target/linux/rockchip/patches-5.15/008-0016-v5.19-media-hantro-Add-support-for-Hantro-G1-on-RK356x.patch b/target/linux/rockchip/patches-5.15/008-0016-v5.19-media-hantro-Add-support-for-Hantro-G1-on-RK356x.patch new file mode 100644 index 000000000..2717ad539 --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0016-v5.19-media-hantro-Add-support-for-Hantro-G1-on-RK356x.patch @@ -0,0 +1,71 @@ +From 5f6bfab6da6531238e899fdf29efd6d0185adc3e Mon Sep 17 00:00:00 2001 +From: Piotr Oniszczuk +Date: Mon, 14 Feb 2022 21:29:53 +0000 +Subject: [PATCH] media: hantro: Add support for Hantro G1 on RK356x + +RK356x has Hantro G1 video decoder capable to decode MPEG2/H.264/VP8 +video formats. + +This patch adds support for RK356x family in existing Hantro +video decoder kernel driver. + +Tested on [1] with FFmpeg v4l2_request code taken from [2] +with MPEG2, H.642 and VP8 samples with results [3]. + +[1] https://github.com/warpme/minimyth2 +[2] https://github.com/LibreELEC/LibreELEC.tv/blob/master/packages/multimedia/ffmpeg/patches/v4l2-request/ffmpeg-001-v4l2-request.patch +[3] https://github.com/warpme/minimyth2/blob/master/video-test-summary.txt + +Signed-off-by: Piotr Oniszczuk +Reviewed-by: Ezequiel Garcia +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +--- + drivers/staging/media/hantro/hantro_drv.c | 1 + + drivers/staging/media/hantro/hantro_hw.h | 1 + + drivers/staging/media/hantro/rockchip_vpu_hw.c | 14 ++++++++++++++ + 3 files changed, 16 insertions(+) + +--- a/drivers/staging/media/hantro/hantro_drv.c ++++ b/drivers/staging/media/hantro/hantro_drv.c +@@ -588,6 +588,7 @@ static const struct of_device_id of_hant + { .compatible = "rockchip,rk3288-vpu", .data = &rk3288_vpu_variant, }, + { .compatible = "rockchip,rk3328-vpu", .data = &rk3328_vpu_variant, }, + { .compatible = "rockchip,rk3399-vpu", .data = &rk3399_vpu_variant, }, ++ { .compatible = "rockchip,rk3568-vpu", .data = &rk3568_vpu_variant, }, + #endif + #ifdef CONFIG_VIDEO_HANTRO_IMX8M + { .compatible = "nxp,imx8mq-vpu", .data = &imx8mq_vpu_variant, }, +--- a/drivers/staging/media/hantro/hantro_hw.h ++++ b/drivers/staging/media/hantro/hantro_hw.h +@@ -215,6 +215,7 @@ extern const struct hantro_variant rk306 + extern const struct hantro_variant rk3288_vpu_variant; + extern const struct hantro_variant rk3328_vpu_variant; + extern const struct hantro_variant rk3399_vpu_variant; ++extern const struct hantro_variant rk3568_vpu_variant; + extern const struct hantro_variant sama5d4_vdec_variant; + + extern const struct hantro_postproc_regs hantro_g1_postproc_regs; +--- a/drivers/staging/media/hantro/rockchip_vpu_hw.c ++++ b/drivers/staging/media/hantro/rockchip_vpu_hw.c +@@ -551,6 +551,20 @@ const struct hantro_variant rk3399_vpu_v + .num_clocks = ARRAY_SIZE(rockchip_vpu_clk_names) + }; + ++const struct hantro_variant rk3568_vpu_variant = { ++ .dec_offset = 0x400, ++ .dec_fmts = rk3399_vpu_dec_fmts, ++ .num_dec_fmts = ARRAY_SIZE(rk3399_vpu_dec_fmts), ++ .codec = HANTRO_MPEG2_DECODER | ++ HANTRO_VP8_DECODER | HANTRO_H264_DECODER, ++ .codec_ops = rk3399_vpu_codec_ops, ++ .irqs = rockchip_vdpu2_irqs, ++ .num_irqs = ARRAY_SIZE(rockchip_vdpu2_irqs), ++ .init = rockchip_vpu_hw_init, ++ .clk_names = rockchip_vpu_clk_names, ++ .num_clocks = ARRAY_SIZE(rockchip_vpu_clk_names) ++}; ++ + const struct hantro_variant px30_vpu_variant = { + .enc_offset = 0x0, + .enc_fmts = rockchip_vpu_enc_fmts, diff --git a/target/linux/rockchip/patches-5.15/008-0017-v5.19-phy-rockchip-inno-usb2-Fix-muxed-interrupt-support.patch b/target/linux/rockchip/patches-5.15/008-0017-v5.19-phy-rockchip-inno-usb2-Fix-muxed-interrupt-support.patch new file mode 100644 index 000000000..ba6b6c5ea --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0017-v5.19-phy-rockchip-inno-usb2-Fix-muxed-interrupt-support.patch @@ -0,0 +1,42 @@ +From 6a98df08ccd55e87947d253b19925691763e755c Mon Sep 17 00:00:00 2001 +From: Samuel Holland +Date: Wed, 13 Apr 2022 22:22:52 -0500 +Subject: [PATCH] phy: rockchip-inno-usb2: Fix muxed interrupt support + +This commit fixes two issues with the muxed interrupt handler. First, +the OTG port has the "bvalid" interrupt enabled, not "linestate". Since +only the linestate interrupt was handled, and not the bvalid interrupt, +plugging in a cable to the OTG port caused an interrupt storm. + +Second, the return values from the individual port IRQ handlers need to +be OR-ed together. Otherwise, the lack of an interrupt from the last +port would cause the handler to erroneously return IRQ_NONE. + +Fixes: ed2b5a8e6b98 ("phy: phy-rockchip-inno-usb2: support muxed interrupts") +Signed-off-by: Samuel Holland +Tested-by: Michael Riesch +Link: https://lore.kernel.org/r/20220414032258.40984-2-samuel@sholland.org +Signed-off-by: Vinod Koul +--- + drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +@@ -948,8 +948,14 @@ static irqreturn_t rockchip_usb2phy_irq( + if (!rport->phy) + continue; + +- /* Handle linestate irq for both otg port and host port */ +- ret = rockchip_usb2phy_linestate_irq(irq, rport); ++ switch (rport->port_id) { ++ case USB2PHY_PORT_OTG: ++ ret |= rockchip_usb2phy_otg_mux_irq(irq, rport); ++ break; ++ case USB2PHY_PORT_HOST: ++ ret |= rockchip_usb2phy_linestate_irq(irq, rport); ++ break; ++ } + } + + return ret; diff --git a/target/linux/rockchip/patches-5.15/008-0018-v5.19-phy-rockchip-inno-usb2-Do-not-check-bvalid-twice.patch b/target/linux/rockchip/patches-5.15/008-0018-v5.19-phy-rockchip-inno-usb2-Do-not-check-bvalid-twice.patch new file mode 100644 index 000000000..8ee9bccde --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0018-v5.19-phy-rockchip-inno-usb2-Do-not-check-bvalid-twice.patch @@ -0,0 +1,37 @@ +From 656f7fcb1272df590e10cb82e07cd2b79bbf60d1 Mon Sep 17 00:00:00 2001 +From: Samuel Holland +Date: Wed, 13 Apr 2022 22:22:53 -0500 +Subject: [PATCH] phy: rockchip-inno-usb2: Do not check bvalid twice + +The bvalid interrupt handler already checks bvalid status. The muxed IRQ +handler just needs to call the other handler (plus any other handlers +that will be added). + +Signed-off-by: Samuel Holland +Tested-by: Michael Riesch +Link: https://lore.kernel.org/r/20220414032258.40984-3-samuel@sholland.org +Signed-off-by: Vinod Koul +--- + drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +@@ -927,13 +927,11 @@ static irqreturn_t rockchip_usb2phy_bval + + static irqreturn_t rockchip_usb2phy_otg_mux_irq(int irq, void *data) + { +- struct rockchip_usb2phy_port *rport = data; +- struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent); ++ irqreturn_t ret = IRQ_NONE; + +- if (property_enabled(rphy->grf, &rport->port_cfg->bvalid_det_st)) +- return rockchip_usb2phy_bvalid_irq(irq, data); +- else +- return IRQ_NONE; ++ ret |= rockchip_usb2phy_bvalid_irq(irq, data); ++ ++ return ret; + } + + static irqreturn_t rockchip_usb2phy_irq(int irq, void *data) diff --git a/target/linux/rockchip/patches-5.15/008-0019-v5.19-phy-rockchip-inno-usb2-Do-not-lock-in-bvalid-IRQ-handler.patch b/target/linux/rockchip/patches-5.15/008-0019-v5.19-phy-rockchip-inno-usb2-Do-not-lock-in-bvalid-IRQ-handler.patch new file mode 100644 index 000000000..b6652143c --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0019-v5.19-phy-rockchip-inno-usb2-Do-not-lock-in-bvalid-IRQ-handler.patch @@ -0,0 +1,31 @@ +From 5a709a46e4270a6130877c052260d9a6d14ac685 Mon Sep 17 00:00:00 2001 +From: Samuel Holland +Date: Wed, 13 Apr 2022 22:22:54 -0500 +Subject: [PATCH] phy: rockchip-inno-usb2: Do not lock in bvalid IRQ handler + +Clearing the IRQ is atomic, so there is no need to hold the mutex. + +Signed-off-by: Samuel Holland +Tested-by: Michael Riesch +Link: https://lore.kernel.org/r/20220414032258.40984-4-samuel@sholland.org +Signed-off-by: Vinod Koul +--- + drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 4 ---- + 1 file changed, 4 deletions(-) + +--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +@@ -913,13 +913,9 @@ static irqreturn_t rockchip_usb2phy_bval + if (!property_enabled(rphy->grf, &rport->port_cfg->bvalid_det_st)) + return IRQ_NONE; + +- mutex_lock(&rport->mutex); +- + /* clear bvalid detect irq pending status */ + property_enable(rphy->grf, &rport->port_cfg->bvalid_det_clr, true); + +- mutex_unlock(&rport->mutex); +- + rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work); + + return IRQ_HANDLED; diff --git a/target/linux/rockchip/patches-5.15/008-0020-v5.19-phy-rockchip-inno-usb2-Support-multi-bit-mask-properties.patch b/target/linux/rockchip/patches-5.15/008-0020-v5.19-phy-rockchip-inno-usb2-Support-multi-bit-mask-properties.patch new file mode 100644 index 000000000..03538c5b8 --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0020-v5.19-phy-rockchip-inno-usb2-Support-multi-bit-mask-properties.patch @@ -0,0 +1,29 @@ +From ffe597d04db2b75d9c547a2d2e07c268c2a33117 Mon Sep 17 00:00:00 2001 +From: Samuel Holland +Date: Wed, 13 Apr 2022 22:22:55 -0500 +Subject: [PATCH] phy: rockchip-inno-usb2: Support multi-bit mask properties + +The "bvalid" and "id" interrupts can trigger on either the rising edge +or the falling edge, so each interrupt has two enable bits and two +status bits. This change allows using a single property for both bits, +checking whether either bit is set. + +Signed-off-by: Samuel Holland +Tested-by: Michael Riesch +Link: https://lore.kernel.org/r/20220414032258.40984-5-samuel@sholland.org +Signed-off-by: Vinod Koul +--- + drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +@@ -253,7 +253,7 @@ static inline bool property_enabled(stru + return false; + + tmp = (orig & mask) >> reg->bitstart; +- return tmp == reg->enable; ++ return tmp != reg->disable; + } + + static int rockchip_usb2phy_clk480m_prepare(struct clk_hw *hw) diff --git a/target/linux/rockchip/patches-5.15/008-0021-v5.19-phy-rockchip-inno-usb2-Handle-bvalid-falling.patch b/target/linux/rockchip/patches-5.15/008-0021-v5.19-phy-rockchip-inno-usb2-Handle-bvalid-falling.patch new file mode 100644 index 000000000..2e0b96e89 --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0021-v5.19-phy-rockchip-inno-usb2-Handle-bvalid-falling.patch @@ -0,0 +1,58 @@ +From 21a470606ed5e8b14980f34cd360595d1cba737f Mon Sep 17 00:00:00 2001 +From: Samuel Holland +Date: Wed, 13 Apr 2022 22:22:56 -0500 +Subject: [PATCH] phy: rockchip-inno-usb2: Handle bvalid falling + +Some SoCs have a bvalid falling interrupt, in addition to bvalid rising. +This interrupt can detect OTG cable plugout immediately, so it can avoid +the delay until the next scheduled work. + +Signed-off-by: Samuel Holland +Tested-by: Michael Riesch +Link: https://lore.kernel.org/r/20220414032258.40984-6-samuel@sholland.org +Signed-off-by: Vinod Koul +--- + drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +@@ -1353,9 +1353,9 @@ static const struct rockchip_usb2phy_cfg + .port_cfgs = { + [USB2PHY_PORT_OTG] = { + .phy_sus = { 0x0100, 8, 0, 0, 0x1d1 }, +- .bvalid_det_en = { 0x3020, 2, 2, 0, 1 }, +- .bvalid_det_st = { 0x3024, 2, 2, 0, 1 }, +- .bvalid_det_clr = { 0x3028, 2, 2, 0, 1 }, ++ .bvalid_det_en = { 0x3020, 3, 2, 0, 3 }, ++ .bvalid_det_st = { 0x3024, 3, 2, 0, 3 }, ++ .bvalid_det_clr = { 0x3028, 3, 2, 0, 3 }, + .ls_det_en = { 0x3020, 0, 0, 0, 1 }, + .ls_det_st = { 0x3024, 0, 0, 0, 1 }, + .ls_det_clr = { 0x3028, 0, 0, 0, 1 }, +@@ -1396,9 +1396,9 @@ static const struct rockchip_usb2phy_cfg + .port_cfgs = { + [USB2PHY_PORT_OTG] = { + .phy_sus = { 0x0100, 15, 0, 0, 0x1d1 }, +- .bvalid_det_en = { 0x0110, 2, 2, 0, 1 }, +- .bvalid_det_st = { 0x0114, 2, 2, 0, 1 }, +- .bvalid_det_clr = { 0x0118, 2, 2, 0, 1 }, ++ .bvalid_det_en = { 0x0110, 3, 2, 0, 3 }, ++ .bvalid_det_st = { 0x0114, 3, 2, 0, 3 }, ++ .bvalid_det_clr = { 0x0118, 3, 2, 0, 3 }, + .ls_det_en = { 0x0110, 0, 0, 0, 1 }, + .ls_det_st = { 0x0114, 0, 0, 0, 1 }, + .ls_det_clr = { 0x0118, 0, 0, 0, 1 }, +@@ -1520,9 +1520,9 @@ static const struct rockchip_usb2phy_cfg + .port_cfgs = { + [USB2PHY_PORT_OTG] = { + .phy_sus = { 0x0000, 8, 0, 0, 0x1d1 }, +- .bvalid_det_en = { 0x0080, 2, 2, 0, 1 }, +- .bvalid_det_st = { 0x0084, 2, 2, 0, 1 }, +- .bvalid_det_clr = { 0x0088, 2, 2, 0, 1 }, ++ .bvalid_det_en = { 0x0080, 3, 2, 0, 3 }, ++ .bvalid_det_st = { 0x0084, 3, 2, 0, 3 }, ++ .bvalid_det_clr = { 0x0088, 3, 2, 0, 3 }, + .utmi_avalid = { 0x00c0, 10, 10, 0, 1 }, + .utmi_bvalid = { 0x00c0, 9, 9, 0, 1 }, + }, diff --git a/target/linux/rockchip/patches-5.15/008-0022-v5.19-phy-rockchip-inno-usb2-Handle-ID-IRQ.patch b/target/linux/rockchip/patches-5.15/008-0022-v5.19-phy-rockchip-inno-usb2-Handle-ID-IRQ.patch new file mode 100644 index 000000000..f5855af91 --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0022-v5.19-phy-rockchip-inno-usb2-Handle-ID-IRQ.patch @@ -0,0 +1,230 @@ +From 51a9b2c03dd3fddc56c2f68740fade2e38a066d0 Mon Sep 17 00:00:00 2001 +From: Samuel Holland +Date: Wed, 13 Apr 2022 22:22:57 -0500 +Subject: [PATCH] phy: rockchip-inno-usb2: Handle ID IRQ + +This supports detecting host mode for the OTG port without an extcon. + +The rv1108 properties are not updated due to lack of documentation. + +Signed-off-by: Samuel Holland +Tested-by: Michael Riesch +Link: https://lore.kernel.org/r/20220414032258.40984-7-samuel@sholland.org +Signed-off-by: Vinod Koul +--- + drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 85 +++++++++++++++++++ + 1 file changed, 85 insertions(+) + +--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +@@ -116,11 +116,15 @@ struct rockchip_chg_det_reg { + * @bvalid_det_en: vbus valid rise detection enable register. + * @bvalid_det_st: vbus valid rise detection status register. + * @bvalid_det_clr: vbus valid rise detection clear register. ++ * @id_det_en: id detection enable register. ++ * @id_det_st: id detection state register. ++ * @id_det_clr: id detection clear register. + * @ls_det_en: linestate detection enable register. + * @ls_det_st: linestate detection state register. + * @ls_det_clr: linestate detection clear register. + * @utmi_avalid: utmi vbus avalid status register. + * @utmi_bvalid: utmi vbus bvalid status register. ++ * @utmi_id: utmi id state register. + * @utmi_ls: utmi linestate state register. + * @utmi_hstdet: utmi host disconnect register. + */ +@@ -129,11 +133,15 @@ struct rockchip_usb2phy_port_cfg { + struct usb2phy_reg bvalid_det_en; + struct usb2phy_reg bvalid_det_st; + struct usb2phy_reg bvalid_det_clr; ++ struct usb2phy_reg id_det_en; ++ struct usb2phy_reg id_det_st; ++ struct usb2phy_reg id_det_clr; + struct usb2phy_reg ls_det_en; + struct usb2phy_reg ls_det_st; + struct usb2phy_reg ls_det_clr; + struct usb2phy_reg utmi_avalid; + struct usb2phy_reg utmi_bvalid; ++ struct usb2phy_reg utmi_id; + struct usb2phy_reg utmi_ls; + struct usb2phy_reg utmi_hstdet; + }; +@@ -161,6 +169,7 @@ struct rockchip_usb2phy_cfg { + * @suspended: phy suspended flag. + * @vbus_attached: otg device vbus status. + * @bvalid_irq: IRQ number assigned for vbus valid rise detection. ++ * @id_irq: IRQ number assigned for ID pin detection. + * @ls_irq: IRQ number assigned for linestate detection. + * @otg_mux_irq: IRQ number which multiplex otg-id/otg-bvalid/linestate + * irqs to one irq in otg-port. +@@ -179,6 +188,7 @@ struct rockchip_usb2phy_port { + bool suspended; + bool vbus_attached; + int bvalid_irq; ++ int id_irq; + int ls_irq; + int otg_mux_irq; + struct mutex mutex; +@@ -426,6 +436,19 @@ static int rockchip_usb2phy_init(struct + if (ret) + goto out; + ++ /* clear id status and enable id detect irq */ ++ ret = property_enable(rphy->grf, ++ &rport->port_cfg->id_det_clr, ++ true); ++ if (ret) ++ goto out; ++ ++ ret = property_enable(rphy->grf, ++ &rport->port_cfg->id_det_en, ++ true); ++ if (ret) ++ goto out; ++ + schedule_delayed_work(&rport->otg_sm_work, + OTG_SCHEDULE_DELAY * 3); + } else { +@@ -921,11 +944,30 @@ static irqreturn_t rockchip_usb2phy_bval + return IRQ_HANDLED; + } + ++static irqreturn_t rockchip_usb2phy_id_irq(int irq, void *data) ++{ ++ struct rockchip_usb2phy_port *rport = data; ++ struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent); ++ bool id; ++ ++ if (!property_enabled(rphy->grf, &rport->port_cfg->id_det_st)) ++ return IRQ_NONE; ++ ++ /* clear id detect irq pending status */ ++ property_enable(rphy->grf, &rport->port_cfg->id_det_clr, true); ++ ++ id = property_enabled(rphy->grf, &rport->port_cfg->utmi_id); ++ extcon_set_state_sync(rphy->edev, EXTCON_USB_HOST, !id); ++ ++ return IRQ_HANDLED; ++} ++ + static irqreturn_t rockchip_usb2phy_otg_mux_irq(int irq, void *data) + { + irqreturn_t ret = IRQ_NONE; + + ret |= rockchip_usb2phy_bvalid_irq(irq, data); ++ ret |= rockchip_usb2phy_id_irq(irq, data); + + return ret; + } +@@ -1023,6 +1065,25 @@ static int rockchip_usb2phy_port_irq_ini + "failed to request otg-bvalid irq handle\n"); + return ret; + } ++ ++ rport->id_irq = of_irq_get_byname(child_np, "otg-id"); ++ if (rport->id_irq < 0) { ++ dev_err(rphy->dev, "no otg-id irq provided\n"); ++ ret = rport->id_irq; ++ return ret; ++ } ++ ++ ret = devm_request_threaded_irq(rphy->dev, rport->id_irq, ++ NULL, ++ rockchip_usb2phy_id_irq, ++ IRQF_ONESHOT, ++ "rockchip_usb2phy_id", ++ rport); ++ if (ret) { ++ dev_err(rphy->dev, ++ "failed to request otg-id irq handle\n"); ++ return ret; ++ } + } + break; + default: +@@ -1297,10 +1358,14 @@ static const struct rockchip_usb2phy_cfg + .bvalid_det_en = { 0x0680, 3, 3, 0, 1 }, + .bvalid_det_st = { 0x0690, 3, 3, 0, 1 }, + .bvalid_det_clr = { 0x06a0, 3, 3, 0, 1 }, ++ .id_det_en = { 0x0680, 6, 5, 0, 3 }, ++ .id_det_st = { 0x0690, 6, 5, 0, 3 }, ++ .id_det_clr = { 0x06a0, 6, 5, 0, 3 }, + .ls_det_en = { 0x0680, 2, 2, 0, 1 }, + .ls_det_st = { 0x0690, 2, 2, 0, 1 }, + .ls_det_clr = { 0x06a0, 2, 2, 0, 1 }, + .utmi_bvalid = { 0x0480, 4, 4, 0, 1 }, ++ .utmi_id = { 0x0480, 1, 1, 0, 1 }, + .utmi_ls = { 0x0480, 3, 2, 0, 1 }, + }, + [USB2PHY_PORT_HOST] = { +@@ -1356,11 +1421,15 @@ static const struct rockchip_usb2phy_cfg + .bvalid_det_en = { 0x3020, 3, 2, 0, 3 }, + .bvalid_det_st = { 0x3024, 3, 2, 0, 3 }, + .bvalid_det_clr = { 0x3028, 3, 2, 0, 3 }, ++ .id_det_en = { 0x3020, 5, 4, 0, 3 }, ++ .id_det_st = { 0x3024, 5, 4, 0, 3 }, ++ .id_det_clr = { 0x3028, 5, 4, 0, 3 }, + .ls_det_en = { 0x3020, 0, 0, 0, 1 }, + .ls_det_st = { 0x3024, 0, 0, 0, 1 }, + .ls_det_clr = { 0x3028, 0, 0, 0, 1 }, + .utmi_avalid = { 0x0120, 10, 10, 0, 1 }, + .utmi_bvalid = { 0x0120, 9, 9, 0, 1 }, ++ .utmi_id = { 0x0120, 6, 6, 0, 1 }, + .utmi_ls = { 0x0120, 5, 4, 0, 1 }, + }, + [USB2PHY_PORT_HOST] = { +@@ -1399,11 +1468,15 @@ static const struct rockchip_usb2phy_cfg + .bvalid_det_en = { 0x0110, 3, 2, 0, 3 }, + .bvalid_det_st = { 0x0114, 3, 2, 0, 3 }, + .bvalid_det_clr = { 0x0118, 3, 2, 0, 3 }, ++ .id_det_en = { 0x0110, 5, 4, 0, 3 }, ++ .id_det_st = { 0x0114, 5, 4, 0, 3 }, ++ .id_det_clr = { 0x0118, 5, 4, 0, 3 }, + .ls_det_en = { 0x0110, 0, 0, 0, 1 }, + .ls_det_st = { 0x0114, 0, 0, 0, 1 }, + .ls_det_clr = { 0x0118, 0, 0, 0, 1 }, + .utmi_avalid = { 0x0120, 10, 10, 0, 1 }, + .utmi_bvalid = { 0x0120, 9, 9, 0, 1 }, ++ .utmi_id = { 0x0120, 6, 6, 0, 1 }, + .utmi_ls = { 0x0120, 5, 4, 0, 1 }, + }, + [USB2PHY_PORT_HOST] = { +@@ -1461,8 +1534,12 @@ static const struct rockchip_usb2phy_cfg + .bvalid_det_en = { 0xe3c0, 3, 3, 0, 1 }, + .bvalid_det_st = { 0xe3e0, 3, 3, 0, 1 }, + .bvalid_det_clr = { 0xe3d0, 3, 3, 0, 1 }, ++ .id_det_en = { 0xe3c0, 5, 4, 0, 3 }, ++ .id_det_st = { 0xe3e0, 5, 4, 0, 3 }, ++ .id_det_clr = { 0xe3d0, 5, 4, 0, 3 }, + .utmi_avalid = { 0xe2ac, 7, 7, 0, 1 }, + .utmi_bvalid = { 0xe2ac, 12, 12, 0, 1 }, ++ .utmi_id = { 0xe2ac, 8, 8, 0, 1 }, + }, + [USB2PHY_PORT_HOST] = { + .phy_sus = { 0xe458, 1, 0, 0x2, 0x1 }, +@@ -1496,8 +1573,12 @@ static const struct rockchip_usb2phy_cfg + .bvalid_det_en = { 0xe3c0, 8, 8, 0, 1 }, + .bvalid_det_st = { 0xe3e0, 8, 8, 0, 1 }, + .bvalid_det_clr = { 0xe3d0, 8, 8, 0, 1 }, ++ .id_det_en = { 0xe3c0, 10, 9, 0, 3 }, ++ .id_det_st = { 0xe3e0, 10, 9, 0, 3 }, ++ .id_det_clr = { 0xe3d0, 10, 9, 0, 3 }, + .utmi_avalid = { 0xe2ac, 10, 10, 0, 1 }, + .utmi_bvalid = { 0xe2ac, 16, 16, 0, 1 }, ++ .utmi_id = { 0xe2ac, 11, 11, 0, 1 }, + }, + [USB2PHY_PORT_HOST] = { + .phy_sus = { 0xe468, 1, 0, 0x2, 0x1 }, +@@ -1523,8 +1604,12 @@ static const struct rockchip_usb2phy_cfg + .bvalid_det_en = { 0x0080, 3, 2, 0, 3 }, + .bvalid_det_st = { 0x0084, 3, 2, 0, 3 }, + .bvalid_det_clr = { 0x0088, 3, 2, 0, 3 }, ++ .id_det_en = { 0x0080, 5, 4, 0, 3 }, ++ .id_det_st = { 0x0084, 5, 4, 0, 3 }, ++ .id_det_clr = { 0x0088, 5, 4, 0, 3 }, + .utmi_avalid = { 0x00c0, 10, 10, 0, 1 }, + .utmi_bvalid = { 0x00c0, 9, 9, 0, 1 }, ++ .utmi_id = { 0x00c0, 6, 6, 0, 1 }, + }, + [USB2PHY_PORT_HOST] = { + /* Select suspend control from controller */ diff --git a/target/linux/rockchip/patches-5.15/008-0023-v5.19-clk-rockchip-Mark-hclk_vo-as-critical-on-rk3568.patch b/target/linux/rockchip/patches-5.15/008-0023-v5.19-clk-rockchip-Mark-hclk_vo-as-critical-on-rk3568.patch new file mode 100644 index 000000000..c49bac1b5 --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0023-v5.19-clk-rockchip-Mark-hclk_vo-as-critical-on-rk3568.patch @@ -0,0 +1,66 @@ +From 6931f85c29d5a0261219cf8a73773d3165806d84 Mon Sep 17 00:00:00 2001 +From: Sascha Hauer +Date: Fri, 22 Apr 2022 09:28:18 +0200 +Subject: [PATCH] clk: rockchip: Mark hclk_vo as critical on rk3568 + +Whenever pclk_vo is enabled hclk_vo must be enabled as well. This is +described in the Reference Manual as: + +| 2.8.6 NIU Clock gating reliance +| +| A part of niu clocks have a dependence on another niu clock in order to +| sharing the internal bus. When these clocks are in use, another niu +| clock must be opened, and cannot be gated. These clocks and the special +| clock on which they are relied are as following: +| +| Clocks which have dependency The clock which can not be gated +| ----------------------------------------------------------------- +| ... +| pclk_vo_niu, hclk_vo_s_niu hclk_vo_niu +| ... + +The clock framework doesn't offer a way to enable clock B whenever clock A is +enabled, at least not when B is not an ancestor of A. Workaround this by +marking hclk_vo as critical so it is never disabled. This is suboptimal in +terms of power consumption, but a stop gap solution until the clock framework +has a way to deal with this. + +We have this clock tree: + +| aclk_vo 2 2 0 300000000 0 0 50000 Y +| aclk_hdcp 0 0 0 300000000 0 0 50000 N +| pclk_vo 2 3 0 75000000 0 0 50000 Y +| pclk_edp_ctrl 0 0 0 75000000 0 0 50000 N +| pclk_dsitx_1 0 0 0 75000000 0 0 50000 N +| pclk_dsitx_0 1 2 0 75000000 0 0 50000 Y +| pclk_hdmi_host 1 2 0 75000000 0 0 50000 Y +| pclk_hdcp 0 0 0 75000000 0 0 50000 N +| hclk_vo 2 5 0 150000000 0 0 50000 Y +| hclk_hdcp 0 0 0 150000000 0 0 50000 N +| hclk_vop 0 2 0 150000000 0 0 50000 N + +Without this patch the edp, dsitx, hdmi and hdcp driver would enable their +clocks which then enables pclk_vo, but hclk_vo stays disabled and register +accesses just hang. hclk_vo is enabled by the VOP2 driver, so reproducibility +of this issue depends on the probe order. + +Signed-off-by: Sascha Hauer +Reviewed-by: Dmitry Osipenko +Reviewed-by: Robin Murphy +Tested-by: Michael Riesch +Link: https://lore.kernel.org/r/20220422072841.2206452-2-s.hauer@pengutronix.de +Signed-off-by: Heiko Stuebner +--- + drivers/clk/rockchip/clk-rk3568.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/clk/rockchip/clk-rk3568.c ++++ b/drivers/clk/rockchip/clk-rk3568.c +@@ -1591,6 +1591,7 @@ static const char *const rk3568_cru_crit + "hclk_php", + "pclk_php", + "hclk_usb", ++ "hclk_vo", + }; + + static const char *const rk3568_pmucru_critical_clocks[] __initconst = { diff --git a/target/linux/rockchip/patches-5.15/008-0024-v5.19-drm-rockchip-Embed-drm_encoder-into-rockchip_decoder.patch b/target/linux/rockchip/patches-5.15/008-0024-v5.19-drm-rockchip-Embed-drm_encoder-into-rockchip_decoder.patch new file mode 100644 index 000000000..238172be7 --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0024-v5.19-drm-rockchip-Embed-drm_encoder-into-rockchip_decoder.patch @@ -0,0 +1,601 @@ +From 540b8f271e53362a308f6bf288d38b630cf3fbd2 Mon Sep 17 00:00:00 2001 +From: Sascha Hauer +Date: Fri, 22 Apr 2022 09:28:19 +0200 +Subject: [PATCH] drm/rockchip: Embed drm_encoder into rockchip_decoder + +The VOP2 driver needs rockchip specific information for a drm_encoder. + +This patch creates a struct rockchip_encoder with a struct drm_encoder +embedded in it. This is used throughout the rockchip driver instead of +struct drm_encoder directly. + +The information the VOP2 drivers needs is the of_graph endpoint node +of the encoder. To ease bisectability this is added here. + +While at it convert the different encoder-to-driverdata macros to +static inline functions in order to gain type safety and readability. + +Signed-off-by: Sascha Hauer +Tested-by: Michael Riesch +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20220422072841.2206452-3-s.hauer@pengutronix.de +--- + .../gpu/drm/rockchip/analogix_dp-rockchip.c | 32 +++++++++++------ + drivers/gpu/drm/rockchip/cdn-dp-core.c | 18 ++++++---- + drivers/gpu/drm/rockchip/cdn-dp-core.h | 2 +- + .../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 17 ++++++---- + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 11 ++++-- + drivers/gpu/drm/rockchip/inno_hdmi.c | 32 +++++++++++------ + drivers/gpu/drm/rockchip/rk3066_hdmi.c | 34 ++++++++++++------- + drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 10 ++++++ + drivers/gpu/drm/rockchip/rockchip_lvds.c | 26 ++++++++------ + 9 files changed, 122 insertions(+), 60 deletions(-) + +--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c ++++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +@@ -40,8 +40,6 @@ + + #define PSR_WAIT_LINE_FLAG_TIMEOUT_MS 100 + +-#define to_dp(nm) container_of(nm, struct rockchip_dp_device, nm) +- + /** + * struct rockchip_dp_chip_data - splite the grf setting of kind of chips + * @lcdsel_grf_reg: grf register offset of lcdc select +@@ -59,7 +57,7 @@ struct rockchip_dp_chip_data { + struct rockchip_dp_device { + struct drm_device *drm_dev; + struct device *dev; +- struct drm_encoder encoder; ++ struct rockchip_encoder encoder; + struct drm_display_mode mode; + + struct clk *pclk; +@@ -73,6 +71,18 @@ struct rockchip_dp_device { + struct analogix_dp_plat_data plat_data; + }; + ++static struct rockchip_dp_device *encoder_to_dp(struct drm_encoder *encoder) ++{ ++ struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder); ++ ++ return container_of(rkencoder, struct rockchip_dp_device, encoder); ++} ++ ++static struct rockchip_dp_device *pdata_encoder_to_dp(struct analogix_dp_plat_data *plat_data) ++{ ++ return container_of(plat_data, struct rockchip_dp_device, plat_data); ++} ++ + static int rockchip_dp_pre_init(struct rockchip_dp_device *dp) + { + reset_control_assert(dp->rst); +@@ -84,7 +94,7 @@ static int rockchip_dp_pre_init(struct r + + static int rockchip_dp_poweron_start(struct analogix_dp_plat_data *plat_data) + { +- struct rockchip_dp_device *dp = to_dp(plat_data); ++ struct rockchip_dp_device *dp = pdata_encoder_to_dp(plat_data); + int ret; + + ret = clk_prepare_enable(dp->pclk); +@@ -105,7 +115,7 @@ static int rockchip_dp_poweron_start(str + + static int rockchip_dp_powerdown(struct analogix_dp_plat_data *plat_data) + { +- struct rockchip_dp_device *dp = to_dp(plat_data); ++ struct rockchip_dp_device *dp = pdata_encoder_to_dp(plat_data); + + clk_disable_unprepare(dp->pclk); + +@@ -166,7 +176,7 @@ struct drm_crtc *rockchip_dp_drm_get_new + static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder, + struct drm_atomic_state *state) + { +- struct rockchip_dp_device *dp = to_dp(encoder); ++ struct rockchip_dp_device *dp = encoder_to_dp(encoder); + struct drm_crtc *crtc; + struct drm_crtc_state *old_crtc_state; + int ret; +@@ -208,7 +218,7 @@ static void rockchip_dp_drm_encoder_enab + static void rockchip_dp_drm_encoder_disable(struct drm_encoder *encoder, + struct drm_atomic_state *state) + { +- struct rockchip_dp_device *dp = to_dp(encoder); ++ struct rockchip_dp_device *dp = encoder_to_dp(encoder); + struct drm_crtc *crtc; + struct drm_crtc_state *new_crtc_state = NULL; + int ret; +@@ -297,7 +307,7 @@ static int rockchip_dp_of_probe(struct r + + static int rockchip_dp_drm_create_encoder(struct rockchip_dp_device *dp) + { +- struct drm_encoder *encoder = &dp->encoder; ++ struct drm_encoder *encoder = &dp->encoder.encoder; + struct drm_device *drm_dev = dp->drm_dev; + struct device *dev = dp->dev; + int ret; +@@ -333,7 +343,7 @@ static int rockchip_dp_bind(struct devic + return ret; + } + +- dp->plat_data.encoder = &dp->encoder; ++ dp->plat_data.encoder = &dp->encoder.encoder; + + ret = analogix_dp_bind(dp->adp, drm_dev); + if (ret) +@@ -341,7 +351,7 @@ static int rockchip_dp_bind(struct devic + + return 0; + err_cleanup_encoder: +- dp->encoder.funcs->destroy(&dp->encoder); ++ dp->encoder.encoder.funcs->destroy(&dp->encoder.encoder); + return ret; + } + +@@ -351,7 +361,7 @@ static void rockchip_dp_unbind(struct de + struct rockchip_dp_device *dp = dev_get_drvdata(dev); + + analogix_dp_unbind(dp->adp); +- dp->encoder.funcs->destroy(&dp->encoder); ++ dp->encoder.encoder.funcs->destroy(&dp->encoder.encoder); + } + + static const struct component_ops rockchip_dp_component_ops = { +--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c ++++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c +@@ -26,11 +26,17 @@ + #include "cdn-dp-reg.h" + #include "rockchip_drm_vop.h" + +-#define connector_to_dp(c) \ +- container_of(c, struct cdn_dp_device, connector) ++static inline struct cdn_dp_device *connector_to_dp(struct drm_connector *connector) ++{ ++ return container_of(connector, struct cdn_dp_device, connector); ++} + +-#define encoder_to_dp(c) \ +- container_of(c, struct cdn_dp_device, encoder) ++static inline struct cdn_dp_device *encoder_to_dp(struct drm_encoder *encoder) ++{ ++ struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder); ++ ++ return container_of(rkencoder, struct cdn_dp_device, encoder); ++} + + #define GRF_SOC_CON9 0x6224 + #define DP_SEL_VOP_LIT BIT(12) +@@ -1024,7 +1030,7 @@ static int cdn_dp_bind(struct device *de + + INIT_WORK(&dp->event_work, cdn_dp_pd_event_work); + +- encoder = &dp->encoder; ++ encoder = &dp->encoder.encoder; + + encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev, + dev->of_node); +@@ -1089,7 +1095,7 @@ err_free_encoder: + static void cdn_dp_unbind(struct device *dev, struct device *master, void *data) + { + struct cdn_dp_device *dp = dev_get_drvdata(dev); +- struct drm_encoder *encoder = &dp->encoder; ++ struct drm_encoder *encoder = &dp->encoder.encoder; + struct drm_connector *connector = &dp->connector; + + cancel_work_sync(&dp->event_work); +--- a/drivers/gpu/drm/rockchip/cdn-dp-core.h ++++ b/drivers/gpu/drm/rockchip/cdn-dp-core.h +@@ -65,7 +65,7 @@ struct cdn_dp_device { + struct device *dev; + struct drm_device *drm_dev; + struct drm_connector connector; +- struct drm_encoder encoder; ++ struct rockchip_encoder encoder; + struct drm_display_mode mode; + struct platform_device *audio_pdev; + struct work_struct event_work; +--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c +@@ -182,8 +182,6 @@ + + #define HIWORD_UPDATE(val, mask) (val | (mask) << 16) + +-#define to_dsi(nm) container_of(nm, struct dw_mipi_dsi_rockchip, nm) +- + enum { + DW_DSI_USAGE_IDLE, + DW_DSI_USAGE_DSI, +@@ -237,7 +235,7 @@ struct rockchip_dw_dsi_chip_data { + + struct dw_mipi_dsi_rockchip { + struct device *dev; +- struct drm_encoder encoder; ++ struct rockchip_encoder encoder; + void __iomem *base; + + struct regmap *grf_regmap; +@@ -272,6 +270,13 @@ struct dw_mipi_dsi_rockchip { + bool dsi_bound; + }; + ++static struct dw_mipi_dsi_rockchip *to_dsi(struct drm_encoder *encoder) ++{ ++ struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder); ++ ++ return container_of(rkencoder, struct dw_mipi_dsi_rockchip, encoder); ++} ++ + struct dphy_pll_parameter_map { + unsigned int max_mbps; + u8 hsfreqrange; +@@ -771,7 +776,7 @@ static void dw_mipi_dsi_encoder_enable(s + int ret, mux; + + mux = drm_of_encoder_active_endpoint_id(dsi->dev->of_node, +- &dsi->encoder); ++ &dsi->encoder.encoder); + if (mux < 0) + return; + +@@ -802,7 +807,7 @@ dw_mipi_dsi_encoder_helper_funcs = { + static int rockchip_dsi_drm_create_encoder(struct dw_mipi_dsi_rockchip *dsi, + struct drm_device *drm_dev) + { +- struct drm_encoder *encoder = &dsi->encoder; ++ struct drm_encoder *encoder = &dsi->encoder.encoder; + int ret; + + encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev, +@@ -960,7 +965,7 @@ static int dw_mipi_dsi_rockchip_bind(str + goto out_pll_clk; + } + +- ret = dw_mipi_dsi_bind(dsi->dmd, &dsi->encoder); ++ ret = dw_mipi_dsi_bind(dsi->dmd, &dsi->encoder.encoder); + if (ret) { + DRM_DEV_ERROR(dev, "Failed to bind: %d\n", ret); + goto out_pll_clk; +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -67,7 +67,7 @@ struct rockchip_hdmi_chip_data { + struct rockchip_hdmi { + struct device *dev; + struct regmap *regmap; +- struct drm_encoder encoder; ++ struct rockchip_encoder encoder; + const struct rockchip_hdmi_chip_data *chip_data; + struct clk *vpll_clk; + struct clk *grf_clk; +@@ -75,7 +75,12 @@ struct rockchip_hdmi { + struct phy *phy; + }; + +-#define to_rockchip_hdmi(x) container_of(x, struct rockchip_hdmi, x) ++static struct rockchip_hdmi *to_rockchip_hdmi(struct drm_encoder *encoder) ++{ ++ struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder); ++ ++ return container_of(rkencoder, struct rockchip_hdmi, encoder); ++} + + static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = { + { +@@ -511,7 +516,7 @@ static int dw_hdmi_rockchip_bind(struct + hdmi->dev = &pdev->dev; + hdmi->chip_data = plat_data->phy_data; + plat_data->phy_data = hdmi; +- encoder = &hdmi->encoder; ++ encoder = &hdmi->encoder.encoder; + + encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); + /* +--- a/drivers/gpu/drm/rockchip/inno_hdmi.c ++++ b/drivers/gpu/drm/rockchip/inno_hdmi.c +@@ -26,8 +26,6 @@ + + #include "inno_hdmi.h" + +-#define to_inno_hdmi(x) container_of(x, struct inno_hdmi, x) +- + struct hdmi_data_info { + int vic; + bool sink_is_hdmi; +@@ -56,7 +54,7 @@ struct inno_hdmi { + void __iomem *regs; + + struct drm_connector connector; +- struct drm_encoder encoder; ++ struct rockchip_encoder encoder; + + struct inno_hdmi_i2c *i2c; + struct i2c_adapter *ddc; +@@ -67,6 +65,18 @@ struct inno_hdmi { + struct drm_display_mode previous_mode; + }; + ++static struct inno_hdmi *encoder_to_inno_hdmi(struct drm_encoder *encoder) ++{ ++ struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder); ++ ++ return container_of(rkencoder, struct inno_hdmi, encoder); ++} ++ ++static struct inno_hdmi *connector_to_inno_hdmi(struct drm_connector *connector) ++{ ++ return container_of(connector, struct inno_hdmi, connector); ++} ++ + enum { + CSC_ITU601_16_235_TO_RGB_0_255_8BIT, + CSC_ITU601_0_255_TO_RGB_0_255_8BIT, +@@ -483,7 +493,7 @@ static void inno_hdmi_encoder_mode_set(s + struct drm_display_mode *mode, + struct drm_display_mode *adj_mode) + { +- struct inno_hdmi *hdmi = to_inno_hdmi(encoder); ++ struct inno_hdmi *hdmi = encoder_to_inno_hdmi(encoder); + + inno_hdmi_setup(hdmi, adj_mode); + +@@ -493,14 +503,14 @@ static void inno_hdmi_encoder_mode_set(s + + static void inno_hdmi_encoder_enable(struct drm_encoder *encoder) + { +- struct inno_hdmi *hdmi = to_inno_hdmi(encoder); ++ struct inno_hdmi *hdmi = encoder_to_inno_hdmi(encoder); + + inno_hdmi_set_pwr_mode(hdmi, NORMAL); + } + + static void inno_hdmi_encoder_disable(struct drm_encoder *encoder) + { +- struct inno_hdmi *hdmi = to_inno_hdmi(encoder); ++ struct inno_hdmi *hdmi = encoder_to_inno_hdmi(encoder); + + inno_hdmi_set_pwr_mode(hdmi, LOWER_PWR); + } +@@ -536,7 +546,7 @@ static struct drm_encoder_helper_funcs i + static enum drm_connector_status + inno_hdmi_connector_detect(struct drm_connector *connector, bool force) + { +- struct inno_hdmi *hdmi = to_inno_hdmi(connector); ++ struct inno_hdmi *hdmi = connector_to_inno_hdmi(connector); + + return (hdmi_readb(hdmi, HDMI_STATUS) & m_HOTPLUG) ? + connector_status_connected : connector_status_disconnected; +@@ -544,7 +554,7 @@ inno_hdmi_connector_detect(struct drm_co + + static int inno_hdmi_connector_get_modes(struct drm_connector *connector) + { +- struct inno_hdmi *hdmi = to_inno_hdmi(connector); ++ struct inno_hdmi *hdmi = connector_to_inno_hdmi(connector); + struct edid *edid; + int ret = 0; + +@@ -599,7 +609,7 @@ static struct drm_connector_helper_funcs + + static int inno_hdmi_register(struct drm_device *drm, struct inno_hdmi *hdmi) + { +- struct drm_encoder *encoder = &hdmi->encoder; ++ struct drm_encoder *encoder = &hdmi->encoder.encoder; + struct device *dev = hdmi->dev; + + encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); +@@ -881,7 +891,7 @@ static int inno_hdmi_bind(struct device + return 0; + err_cleanup_hdmi: + hdmi->connector.funcs->destroy(&hdmi->connector); +- hdmi->encoder.funcs->destroy(&hdmi->encoder); ++ hdmi->encoder.encoder.funcs->destroy(&hdmi->encoder.encoder); + err_put_adapter: + i2c_put_adapter(hdmi->ddc); + err_disable_clk: +@@ -895,7 +905,7 @@ static void inno_hdmi_unbind(struct devi + struct inno_hdmi *hdmi = dev_get_drvdata(dev); + + hdmi->connector.funcs->destroy(&hdmi->connector); +- hdmi->encoder.funcs->destroy(&hdmi->encoder); ++ hdmi->encoder.encoder.funcs->destroy(&hdmi->encoder.encoder); + + i2c_put_adapter(hdmi->ddc); + clk_disable_unprepare(hdmi->pclk); +--- a/drivers/gpu/drm/rockchip/rk3066_hdmi.c ++++ b/drivers/gpu/drm/rockchip/rk3066_hdmi.c +@@ -47,7 +47,7 @@ struct rk3066_hdmi { + void __iomem *regs; + + struct drm_connector connector; +- struct drm_encoder encoder; ++ struct rockchip_encoder encoder; + + struct rk3066_hdmi_i2c *i2c; + struct i2c_adapter *ddc; +@@ -58,7 +58,17 @@ struct rk3066_hdmi { + struct drm_display_mode previous_mode; + }; + +-#define to_rk3066_hdmi(x) container_of(x, struct rk3066_hdmi, x) ++static struct rk3066_hdmi *encoder_to_rk3066_hdmi(struct drm_encoder *encoder) ++{ ++ struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder); ++ ++ return container_of(rkencoder, struct rk3066_hdmi, encoder); ++} ++ ++static struct rk3066_hdmi *connector_to_rk3066_hdmi(struct drm_connector *connector) ++{ ++ return container_of(connector, struct rk3066_hdmi, connector); ++} + + static inline u8 hdmi_readb(struct rk3066_hdmi *hdmi, u16 offset) + { +@@ -380,7 +390,7 @@ rk3066_hdmi_encoder_mode_set(struct drm_ + struct drm_display_mode *mode, + struct drm_display_mode *adj_mode) + { +- struct rk3066_hdmi *hdmi = to_rk3066_hdmi(encoder); ++ struct rk3066_hdmi *hdmi = encoder_to_rk3066_hdmi(encoder); + + /* Store the display mode for plugin/DPMS poweron events. */ + memcpy(&hdmi->previous_mode, adj_mode, sizeof(hdmi->previous_mode)); +@@ -388,7 +398,7 @@ rk3066_hdmi_encoder_mode_set(struct drm_ + + static void rk3066_hdmi_encoder_enable(struct drm_encoder *encoder) + { +- struct rk3066_hdmi *hdmi = to_rk3066_hdmi(encoder); ++ struct rk3066_hdmi *hdmi = encoder_to_rk3066_hdmi(encoder); + int mux, val; + + mux = drm_of_encoder_active_endpoint_id(hdmi->dev->of_node, encoder); +@@ -407,7 +417,7 @@ static void rk3066_hdmi_encoder_enable(s + + static void rk3066_hdmi_encoder_disable(struct drm_encoder *encoder) + { +- struct rk3066_hdmi *hdmi = to_rk3066_hdmi(encoder); ++ struct rk3066_hdmi *hdmi = encoder_to_rk3066_hdmi(encoder); + + DRM_DEV_DEBUG(hdmi->dev, "hdmi encoder disable\n"); + +@@ -455,7 +465,7 @@ struct drm_encoder_helper_funcs rk3066_h + static enum drm_connector_status + rk3066_hdmi_connector_detect(struct drm_connector *connector, bool force) + { +- struct rk3066_hdmi *hdmi = to_rk3066_hdmi(connector); ++ struct rk3066_hdmi *hdmi = connector_to_rk3066_hdmi(connector); + + return (hdmi_readb(hdmi, HDMI_HPG_MENS_STA) & HDMI_HPG_IN_STATUS_HIGH) ? + connector_status_connected : connector_status_disconnected; +@@ -463,7 +473,7 @@ rk3066_hdmi_connector_detect(struct drm_ + + static int rk3066_hdmi_connector_get_modes(struct drm_connector *connector) + { +- struct rk3066_hdmi *hdmi = to_rk3066_hdmi(connector); ++ struct rk3066_hdmi *hdmi = connector_to_rk3066_hdmi(connector); + struct edid *edid; + int ret = 0; + +@@ -496,9 +506,9 @@ rk3066_hdmi_connector_mode_valid(struct + static struct drm_encoder * + rk3066_hdmi_connector_best_encoder(struct drm_connector *connector) + { +- struct rk3066_hdmi *hdmi = to_rk3066_hdmi(connector); ++ struct rk3066_hdmi *hdmi = connector_to_rk3066_hdmi(connector); + +- return &hdmi->encoder; ++ return &hdmi->encoder.encoder; + } + + static int +@@ -538,7 +548,7 @@ struct drm_connector_helper_funcs rk3066 + static int + rk3066_hdmi_register(struct drm_device *drm, struct rk3066_hdmi *hdmi) + { +- struct drm_encoder *encoder = &hdmi->encoder; ++ struct drm_encoder *encoder = &hdmi->encoder.encoder; + struct device *dev = hdmi->dev; + + encoder->possible_crtcs = +@@ -816,7 +826,7 @@ static int rk3066_hdmi_bind(struct devic + + err_cleanup_hdmi: + hdmi->connector.funcs->destroy(&hdmi->connector); +- hdmi->encoder.funcs->destroy(&hdmi->encoder); ++ hdmi->encoder.encoder.funcs->destroy(&hdmi->encoder.encoder); + err_disable_i2c: + i2c_put_adapter(hdmi->ddc); + err_disable_hclk: +@@ -831,7 +841,7 @@ static void rk3066_hdmi_unbind(struct de + struct rk3066_hdmi *hdmi = dev_get_drvdata(dev); + + hdmi->connector.funcs->destroy(&hdmi->connector); +- hdmi->encoder.funcs->destroy(&hdmi->encoder); ++ hdmi->encoder.encoder.funcs->destroy(&hdmi->encoder.encoder); + + i2c_put_adapter(hdmi->ddc); + clk_disable_unprepare(hdmi->hclk); +--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h +@@ -52,6 +52,10 @@ struct rockchip_drm_private { + struct mutex psr_list_lock; + }; + ++struct rockchip_encoder { ++ struct drm_encoder encoder; ++}; ++ + int rockchip_drm_dma_attach_device(struct drm_device *drm_dev, + struct device *dev); + void rockchip_drm_dma_detach_device(struct drm_device *drm_dev, +@@ -67,4 +71,10 @@ extern struct platform_driver rockchip_d + extern struct platform_driver rockchip_lvds_driver; + extern struct platform_driver vop_platform_driver; + extern struct platform_driver rk3066_hdmi_driver; ++ ++static inline struct rockchip_encoder *to_rockchip_encoder(struct drm_encoder *encoder) ++{ ++ return container_of(encoder, struct rockchip_encoder, encoder); ++} ++ + #endif /* _ROCKCHIP_DRM_DRV_H_ */ +--- a/drivers/gpu/drm/rockchip/rockchip_lvds.c ++++ b/drivers/gpu/drm/rockchip/rockchip_lvds.c +@@ -35,12 +35,6 @@ + + struct rockchip_lvds; + +-#define connector_to_lvds(c) \ +- container_of(c, struct rockchip_lvds, connector) +- +-#define encoder_to_lvds(c) \ +- container_of(c, struct rockchip_lvds, encoder) +- + /** + * struct rockchip_lvds_soc_data - rockchip lvds Soc private data + * @probe: LVDS platform probe function +@@ -64,10 +58,22 @@ struct rockchip_lvds { + struct drm_panel *panel; + struct drm_bridge *bridge; + struct drm_connector connector; +- struct drm_encoder encoder; ++ struct rockchip_encoder encoder; + struct dev_pin_info *pins; + }; + ++static inline struct rockchip_lvds *connector_to_lvds(struct drm_connector *connector) ++{ ++ return container_of(connector, struct rockchip_lvds, connector); ++} ++ ++static inline struct rockchip_lvds *encoder_to_lvds(struct drm_encoder *encoder) ++{ ++ struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder); ++ ++ return container_of(rkencoder, struct rockchip_lvds, encoder); ++} ++ + static inline void rk3288_writel(struct rockchip_lvds *lvds, u32 offset, + u32 val) + { +@@ -600,7 +606,7 @@ static int rockchip_lvds_bind(struct dev + goto err_put_remote; + } + +- encoder = &lvds->encoder; ++ encoder = &lvds->encoder.encoder; + encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev, + dev->of_node); + +@@ -665,10 +671,10 @@ static void rockchip_lvds_unbind(struct + const struct drm_encoder_helper_funcs *encoder_funcs; + + encoder_funcs = lvds->soc_data->helper_funcs; +- encoder_funcs->disable(&lvds->encoder); ++ encoder_funcs->disable(&lvds->encoder.encoder); + pm_runtime_disable(dev); + drm_connector_cleanup(&lvds->connector); +- drm_encoder_cleanup(&lvds->encoder); ++ drm_encoder_cleanup(&lvds->encoder.encoder); + } + + static const struct component_ops rockchip_lvds_component_ops = { diff --git a/target/linux/rockchip/patches-5.15/008-0025-v5.19-drm-rockchip-Add-crtc_endpoint_id-to-rockchip_encoder.patch b/target/linux/rockchip/patches-5.15/008-0025-v5.19-drm-rockchip-Add-crtc_endpoint_id-to-rockchip_encoder.patch new file mode 100644 index 000000000..e80ecfddf --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0025-v5.19-drm-rockchip-Add-crtc_endpoint_id-to-rockchip_encoder.patch @@ -0,0 +1,88 @@ +From cf544c6a885c52d79e4d8bf139fb8cb63a878512 Mon Sep 17 00:00:00 2001 +From: Sascha Hauer +Date: Fri, 22 Apr 2022 09:28:20 +0200 +Subject: [PATCH] drm/rockchip: Add crtc_endpoint_id to rockchip_encoder + +The VOP2 has an interface mux which decides to which encoder(s) a CRTC +is routed to. The encoders and CRTCs are connected via of_graphs in the +device tree. When given an encoder the VOP2 driver needs to know to +which internal register setting this encoder matches. For this the VOP2 +binding offers different endpoints, one for each possible encoder. The +endpoint ids of these endpoints are used as a key from an encoders +device tree description to the internal register setting. + +This patch adds the key aka endpoint id to struct rockchip_encoder plus +a function to read the endpoint id starting from the encoders device +node. + +Signed-off-by: Sascha Hauer +Tested-by: Michael Riesch +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20220422072841.2206452-4-s.hauer@pengutronix.de +--- + drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 33 +++++++++++++++++++++ + drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 4 ++- + 2 files changed, 36 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +@@ -255,6 +255,39 @@ static struct platform_driver *rockchip_ + static int num_rockchip_sub_drivers; + + /* ++ * Get the endpoint id of the remote endpoint of the given encoder. This ++ * information is used by the VOP2 driver to identify the encoder. ++ * ++ * @rkencoder: The encoder to get the remote endpoint id from ++ * @np: The encoder device node ++ * @port: The number of the port leading to the VOP2 ++ * @reg: The endpoint number leading to the VOP2 ++ */ ++int rockchip_drm_encoder_set_crtc_endpoint_id(struct rockchip_encoder *rkencoder, ++ struct device_node *np, int port, int reg) ++{ ++ struct of_endpoint ep; ++ struct device_node *en, *ren; ++ int ret; ++ ++ en = of_graph_get_endpoint_by_regs(np, port, reg); ++ if (!en) ++ return -ENOENT; ++ ++ ren = of_graph_get_remote_endpoint(en); ++ if (!ren) ++ return -ENOENT; ++ ++ ret = of_graph_parse_endpoint(ren, &ep); ++ if (ret) ++ return ret; ++ ++ rkencoder->crtc_endpoint_id = ep.id; ++ ++ return 0; ++} ++ ++/* + * Check if a vop endpoint is leading to a rockchip subdriver or bridge. + * Should be called from the component bind stage of the drivers + * to ensure that all subdrivers are probed. +--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h +@@ -53,6 +53,7 @@ struct rockchip_drm_private { + }; + + struct rockchip_encoder { ++ int crtc_endpoint_id; + struct drm_encoder encoder; + }; + +@@ -61,7 +62,8 @@ int rockchip_drm_dma_attach_device(struc + void rockchip_drm_dma_detach_device(struct drm_device *drm_dev, + struct device *dev); + int rockchip_drm_wait_vact_end(struct drm_crtc *crtc, unsigned int mstimeout); +- ++int rockchip_drm_encoder_set_crtc_endpoint_id(struct rockchip_encoder *rencoder, ++ struct device_node *np, int port, int reg); + 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; diff --git a/target/linux/rockchip/patches-5.15/008-0026-v5.19-drm-rockchip-dw_hdmi-rename-vpll-clock-to-reference-clock.patch b/target/linux/rockchip/patches-5.15/008-0026-v5.19-drm-rockchip-dw_hdmi-rename-vpll-clock-to-reference-clock.patch new file mode 100644 index 000000000..dce5b3797 --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0026-v5.19-drm-rockchip-dw_hdmi-rename-vpll-clock-to-reference-clock.patch @@ -0,0 +1,93 @@ +From a9d37e684492ab5db1cce28b655e20c01191873f Mon Sep 17 00:00:00 2001 +From: Sascha Hauer +Date: Fri, 22 Apr 2022 09:28:21 +0200 +Subject: [PATCH] drm/rockchip: dw_hdmi: rename vpll clock to reference clock + +"vpll" is a misnomer. A clock input to a device should be named after +the usage in the device, not after the clock that drives it. On the +rk3568 the same clock is driven by the HPLL. +To fix that, this patch renames the vpll clock to ref clock. The clock +name "vpll" is left for compatibility to old device trees. + +Signed-off-by: Sascha Hauer +Reviewed-by: Dmitry Osipenko +Tested-by: Michael Riesch +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20220422072841.2206452-5-s.hauer@pengutronix.de +--- + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 27 +++++++++++---------- + 1 file changed, 14 insertions(+), 13 deletions(-) + +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -69,7 +69,7 @@ struct rockchip_hdmi { + struct regmap *regmap; + struct rockchip_encoder encoder; + const struct rockchip_hdmi_chip_data *chip_data; +- struct clk *vpll_clk; ++ struct clk *ref_clk; + struct clk *grf_clk; + struct dw_hdmi *hdmi; + struct phy *phy; +@@ -201,14 +201,15 @@ static int rockchip_hdmi_parse_dt(struct + return PTR_ERR(hdmi->regmap); + } + +- hdmi->vpll_clk = devm_clk_get(hdmi->dev, "vpll"); +- if (PTR_ERR(hdmi->vpll_clk) == -ENOENT) { +- hdmi->vpll_clk = NULL; +- } else if (PTR_ERR(hdmi->vpll_clk) == -EPROBE_DEFER) { ++ hdmi->ref_clk = devm_clk_get_optional(hdmi->dev, "ref"); ++ if (!hdmi->ref_clk) ++ hdmi->ref_clk = devm_clk_get_optional(hdmi->dev, "vpll"); ++ ++ if (PTR_ERR(hdmi->ref_clk) == -EPROBE_DEFER) { + return -EPROBE_DEFER; +- } else if (IS_ERR(hdmi->vpll_clk)) { +- DRM_DEV_ERROR(hdmi->dev, "failed to get vpll clock\n"); +- return PTR_ERR(hdmi->vpll_clk); ++ } else if (IS_ERR(hdmi->ref_clk)) { ++ DRM_DEV_ERROR(hdmi->dev, "failed to get reference clock\n"); ++ return PTR_ERR(hdmi->ref_clk); + } + + hdmi->grf_clk = devm_clk_get(hdmi->dev, "grf"); +@@ -262,7 +263,7 @@ static void dw_hdmi_rockchip_encoder_mod + { + struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder); + +- clk_set_rate(hdmi->vpll_clk, adj_mode->clock * 1000); ++ clk_set_rate(hdmi->ref_clk, adj_mode->clock * 1000); + } + + static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder) +@@ -542,9 +543,9 @@ static int dw_hdmi_rockchip_bind(struct + return ret; + } + +- ret = clk_prepare_enable(hdmi->vpll_clk); ++ ret = clk_prepare_enable(hdmi->ref_clk); + if (ret) { +- DRM_DEV_ERROR(hdmi->dev, "Failed to enable HDMI vpll: %d\n", ++ DRM_DEV_ERROR(hdmi->dev, "Failed to enable HDMI reference clock: %d\n", + ret); + return ret; + } +@@ -563,7 +564,7 @@ static int dw_hdmi_rockchip_bind(struct + if (IS_ERR(hdmi->hdmi)) { + ret = PTR_ERR(hdmi->hdmi); + drm_encoder_cleanup(encoder); +- clk_disable_unprepare(hdmi->vpll_clk); ++ clk_disable_unprepare(hdmi->ref_clk); + } + + return ret; +@@ -575,7 +576,7 @@ static void dw_hdmi_rockchip_unbind(stru + struct rockchip_hdmi *hdmi = dev_get_drvdata(dev); + + dw_hdmi_unbind(hdmi->hdmi); +- clk_disable_unprepare(hdmi->vpll_clk); ++ clk_disable_unprepare(hdmi->ref_clk); + } + + static const struct component_ops dw_hdmi_rockchip_ops = { diff --git a/target/linux/rockchip/patches-5.15/008-0027-v5.19-drm-rockchip-dw_hdmi-add-rk3568-support.patch b/target/linux/rockchip/patches-5.15/008-0027-v5.19-drm-rockchip-dw_hdmi-add-rk3568-support.patch new file mode 100644 index 000000000..799f159ca --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0027-v5.19-drm-rockchip-dw_hdmi-add-rk3568-support.patch @@ -0,0 +1,84 @@ +From 28bbb5ffbe32741e65d798070986d212cc11e1bb Mon Sep 17 00:00:00 2001 +From: Sascha Hauer +Date: Fri, 22 Apr 2022 09:28:24 +0200 +Subject: [PATCH] drm/rockchip: dw_hdmi: add rk3568 support + +Add a new dw_hdmi_plat_data struct and new compatible for rk3568. + +Signed-off-by: Benjamin Gaignard +Signed-off-by: Sascha Hauer +Tested-by: Michael Riesch +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20220422072841.2206452-8-s.hauer@pengutronix.de +--- + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 31 +++++++++++++++++++++ + 1 file changed, 31 insertions(+) + +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -50,6 +50,10 @@ + #define RK3399_GRF_SOC_CON20 0x6250 + #define RK3399_HDMI_LCDC_SEL BIT(6) + ++#define RK3568_GRF_VO_CON1 0x0364 ++#define RK3568_HDMI_SDAIN_MSK BIT(15) ++#define RK3568_HDMI_SCLIN_MSK BIT(14) ++ + #define HIWORD_UPDATE(val, mask) (val | (mask) << 16) + + /** +@@ -473,6 +477,19 @@ static const struct dw_hdmi_plat_data rk + .use_drm_infoframe = true, + }; + ++static struct rockchip_hdmi_chip_data rk3568_chip_data = { ++ .lcdsel_grf_reg = -1, ++}; ++ ++static const struct dw_hdmi_plat_data rk3568_hdmi_drv_data = { ++ .mode_valid = dw_hdmi_rockchip_mode_valid, ++ .mpll_cfg = rockchip_mpll_cfg, ++ .cur_ctr = rockchip_cur_ctr, ++ .phy_config = rockchip_phy_config, ++ .phy_data = &rk3568_chip_data, ++ .use_drm_infoframe = true, ++}; ++ + static const struct of_device_id dw_hdmi_rockchip_dt_ids[] = { + { .compatible = "rockchip,rk3228-dw-hdmi", + .data = &rk3228_hdmi_drv_data +@@ -486,6 +503,9 @@ static const struct of_device_id dw_hdmi + { .compatible = "rockchip,rk3399-dw-hdmi", + .data = &rk3399_hdmi_drv_data + }, ++ { .compatible = "rockchip,rk3568-dw-hdmi", ++ .data = &rk3568_hdmi_drv_data ++ }, + {}, + }; + MODULE_DEVICE_TABLE(of, dw_hdmi_rockchip_dt_ids); +@@ -520,6 +540,9 @@ static int dw_hdmi_rockchip_bind(struct + 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 +@@ -550,6 +573,14 @@ static int dw_hdmi_rockchip_bind(struct + return ret; + } + ++ if (hdmi->chip_data == &rk3568_chip_data) { ++ regmap_write(hdmi->regmap, RK3568_GRF_VO_CON1, ++ HIWORD_UPDATE(RK3568_HDMI_SDAIN_MSK | ++ RK3568_HDMI_SCLIN_MSK, ++ RK3568_HDMI_SDAIN_MSK | ++ RK3568_HDMI_SCLIN_MSK)); ++ } ++ + drm_encoder_helper_add(encoder, &dw_hdmi_rockchip_encoder_helper_funcs); + drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS); + diff --git a/target/linux/rockchip/patches-5.15/008-0028-v5.19-drm-rockchip-dw_hdmi-add-regulator-support.patch b/target/linux/rockchip/patches-5.15/008-0028-v5.19-drm-rockchip-dw_hdmi-add-regulator-support.patch new file mode 100644 index 000000000..4a67db21d --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0028-v5.19-drm-rockchip-dw_hdmi-add-regulator-support.patch @@ -0,0 +1,109 @@ +From ca80c4eb4b01a7f1c2f333d0a329937ef9c7f03a Mon Sep 17 00:00:00 2001 +From: Sascha Hauer +Date: Fri, 22 Apr 2022 09:28:26 +0200 +Subject: [PATCH] drm/rockchip: dw_hdmi: add regulator support + +The RK3568 has HDMI_TX_AVDD0V9 and HDMI_TX_AVDD_1V8 supply inputs needed +for the HDMI port. add support for these to the driver for boards which +have them supplied by switchable regulators. + +Signed-off-by: Sascha Hauer +Reviewed-by: Dmitry Osipenko +Tested-by: Michael Riesch +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20220422072841.2206452-10-s.hauer@pengutronix.de +--- + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 41 +++++++++++++++++++-- + 1 file changed, 38 insertions(+), 3 deletions(-) + +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -76,6 +77,8 @@ struct rockchip_hdmi { + struct clk *ref_clk; + struct clk *grf_clk; + struct dw_hdmi *hdmi; ++ struct regulator *avdd_0v9; ++ struct regulator *avdd_1v8; + struct phy *phy; + }; + +@@ -226,6 +229,14 @@ static int rockchip_hdmi_parse_dt(struct + return PTR_ERR(hdmi->grf_clk); + } + ++ hdmi->avdd_0v9 = devm_regulator_get(hdmi->dev, "avdd-0v9"); ++ if (IS_ERR(hdmi->avdd_0v9)) ++ return PTR_ERR(hdmi->avdd_0v9); ++ ++ hdmi->avdd_1v8 = devm_regulator_get(hdmi->dev, "avdd-1v8"); ++ if (IS_ERR(hdmi->avdd_1v8)) ++ return PTR_ERR(hdmi->avdd_1v8); ++ + return 0; + } + +@@ -566,11 +577,23 @@ static int dw_hdmi_rockchip_bind(struct + return ret; + } + ++ ret = regulator_enable(hdmi->avdd_0v9); ++ if (ret) { ++ DRM_DEV_ERROR(hdmi->dev, "failed to enable avdd0v9: %d\n", ret); ++ goto err_avdd_0v9; ++ } ++ ++ ret = regulator_enable(hdmi->avdd_1v8); ++ if (ret) { ++ DRM_DEV_ERROR(hdmi->dev, "failed to enable avdd1v8: %d\n", ret); ++ goto err_avdd_1v8; ++ } ++ + ret = clk_prepare_enable(hdmi->ref_clk); + if (ret) { + DRM_DEV_ERROR(hdmi->dev, "Failed to enable HDMI reference clock: %d\n", + ret); +- return ret; ++ goto err_clk; + } + + if (hdmi->chip_data == &rk3568_chip_data) { +@@ -594,10 +617,19 @@ static int dw_hdmi_rockchip_bind(struct + */ + if (IS_ERR(hdmi->hdmi)) { + ret = PTR_ERR(hdmi->hdmi); +- drm_encoder_cleanup(encoder); +- clk_disable_unprepare(hdmi->ref_clk); ++ goto err_bind; + } + ++ return 0; ++ ++err_bind: ++ drm_encoder_cleanup(encoder); ++ clk_disable_unprepare(hdmi->ref_clk); ++err_clk: ++ regulator_disable(hdmi->avdd_1v8); ++err_avdd_1v8: ++ regulator_disable(hdmi->avdd_0v9); ++err_avdd_0v9: + return ret; + } + +@@ -608,6 +640,9 @@ static void dw_hdmi_rockchip_unbind(stru + + dw_hdmi_unbind(hdmi->hdmi); + clk_disable_unprepare(hdmi->ref_clk); ++ ++ regulator_disable(hdmi->avdd_1v8); ++ regulator_disable(hdmi->avdd_0v9); + } + + static const struct component_ops dw_hdmi_rockchip_ops = { diff --git a/target/linux/rockchip/patches-5.15/008-0029-v5.19-drm-rockchip-Make-VOP-driver-optional.patch b/target/linux/rockchip/patches-5.15/008-0029-v5.19-drm-rockchip-Make-VOP-driver-optional.patch new file mode 100644 index 000000000..0f92c0774 --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0029-v5.19-drm-rockchip-Make-VOP-driver-optional.patch @@ -0,0 +1,65 @@ +From b382406a2cf4afaa7320a7ad4b298ed6e2675437 Mon Sep 17 00:00:00 2001 +From: Sascha Hauer +Date: Fri, 22 Apr 2022 09:28:38 +0200 +Subject: [PATCH] drm/rockchip: Make VOP driver optional + +With upcoming VOP2 support VOP won't be the only choice anymore, so make +the VOP driver optional. + +This also adds a dependency from ROCKCHIP_ANALOGIX_DP to ROCKCHIP_VOP, +because that driver currently only links and works with the VOP driver. + +Signed-off-by: Sascha Hauer +Tested-by: Michael Riesch +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20220422072841.2206452-22-s.hauer@pengutronix.de +--- + drivers/gpu/drm/rockchip/Kconfig | 8 ++++++++ + drivers/gpu/drm/rockchip/Makefile | 3 ++- + drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 2 +- + 3 files changed, 11 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/rockchip/Kconfig ++++ b/drivers/gpu/drm/rockchip/Kconfig +@@ -22,8 +22,16 @@ config DRM_ROCKCHIP + + if DRM_ROCKCHIP + ++config ROCKCHIP_VOP ++ bool "Rockchip VOP driver" ++ default y ++ help ++ This selects support for the VOP driver. You should enable it ++ on older SoCs. ++ + config ROCKCHIP_ANALOGIX_DP + bool "Rockchip specific extensions for Analogix DP driver" ++ depends on ROCKCHIP_VOP + help + This selects support for Rockchip SoC specific extensions + for the Analogix Core DP driver. If you want to enable DP +--- a/drivers/gpu/drm/rockchip/Makefile ++++ b/drivers/gpu/drm/rockchip/Makefile +@@ -4,9 +4,10 @@ + # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. + + rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \ +- rockchip_drm_gem.o rockchip_drm_vop.o rockchip_vop_reg.o ++ rockchip_drm_gem.o + rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += rockchip_drm_fbdev.o + ++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 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +@@ -502,7 +502,7 @@ static int __init rockchip_drm_init(void + int ret; + + num_rockchip_sub_drivers = 0; +- ADD_ROCKCHIP_SUB_DRIVER(vop_platform_driver, CONFIG_DRM_ROCKCHIP); ++ ADD_ROCKCHIP_SUB_DRIVER(vop_platform_driver, CONFIG_ROCKCHIP_VOP); + ADD_ROCKCHIP_SUB_DRIVER(rockchip_lvds_driver, + CONFIG_ROCKCHIP_LVDS); + ADD_ROCKCHIP_SUB_DRIVER(rockchip_dp_driver, diff --git a/target/linux/rockchip/patches-5.15/008-0030-v5.19-drm-rockchip-Add-VOP2-driver.patch b/target/linux/rockchip/patches-5.15/008-0030-v5.19-drm-rockchip-Add-VOP2-driver.patch new file mode 100644 index 000000000..c33f9a572 --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0030-v5.19-drm-rockchip-Add-VOP2-driver.patch @@ -0,0 +1,149 @@ +From 604be85547ce4d61b89292d2f9a78c721b778c16 Mon Sep 17 00:00:00 2001 +From: Andy Yan +Date: Fri, 22 Apr 2022 09:28:39 +0200 +Subject: [PATCH] drm/rockchip: Add VOP2 driver + +The VOP2 unit is found on Rockchip SoCs beginning with rk3566/rk3568. +It replaces the VOP unit found in the older Rockchip SoCs. + +This driver has been derived from the downstream Rockchip Kernel and +heavily modified: + +- All nonstandard DRM properties have been removed +- dropped struct vop2_plane_state and pass around less data between + functions +- Dropped all DRM_FORMAT_* not known on upstream +- rework register access to get rid of excessively used macros +- Drop all waiting for framesyncs + +The driver is tested with HDMI and MIPI-DSI display on a RK3568-EVB +board. Overlay support is tested with the modetest utility. AFBC support +on the cluster windows is tested with weston-simple-dmabuf-egl on +weston using the (yet to be upstreamed) panfrost driver support. + +Signed-off-by: Andy Yan +Co-Developed-by: Sascha Hauer +Signed-off-by: Sascha Hauer +Tested-by: Michael Riesch +[dt-binding-header:] +Acked-by: Rob Herring +[moved dt-binding header from dt-nodes patch to here + and made checkpatch --strict happier] +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20220422072841.2206452-23-s.hauer@pengutronix.de +--- + drivers/gpu/drm/rockchip/Kconfig | 6 + + drivers/gpu/drm/rockchip/Makefile | 1 + + drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 1 + + drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 6 +- + drivers/gpu/drm/rockchip/rockchip_drm_fb.c | 2 + + drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 14 + + drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 2706 ++++++++++++++++++ + drivers/gpu/drm/rockchip/rockchip_drm_vop2.h | 477 +++ + drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 281 ++ + include/dt-bindings/soc/rockchip,vop2.h | 14 + + 10 files changed, 3507 insertions(+), 1 deletion(-) + create mode 100644 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c + create mode 100644 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h + create mode 100644 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c + create mode 100644 include/dt-bindings/soc/rockchip,vop2.h + +--- a/drivers/gpu/drm/rockchip/Kconfig ++++ b/drivers/gpu/drm/rockchip/Kconfig +@@ -29,6 +29,12 @@ config ROCKCHIP_VOP + This selects support for the VOP driver. You should enable it + on older SoCs. + ++config ROCKCHIP_VOP2 ++ bool "Rockchip VOP2 driver" ++ help ++ This selects support for the VOP2 driver. The VOP2 hardware is ++ first found on the RK3568. ++ + config ROCKCHIP_ANALOGIX_DP + bool "Rockchip specific extensions for Analogix DP driver" + depends on ROCKCHIP_VOP +--- a/drivers/gpu/drm/rockchip/Makefile ++++ b/drivers/gpu/drm/rockchip/Makefile +@@ -7,6 +7,7 @@ rockchipdrm-y := rockchip_drm_drv.o rock + rockchip_drm_gem.o + rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += rockchip_drm_fbdev.o + ++rockchipdrm-$(CONFIG_ROCKCHIP_VOP2) += rockchip_drm_vop2.o rockchip_vop2_reg.o + 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 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +@@ -503,6 +503,7 @@ static int __init rockchip_drm_init(void + + num_rockchip_sub_drivers = 0; + ADD_ROCKCHIP_SUB_DRIVER(vop_platform_driver, CONFIG_ROCKCHIP_VOP); ++ ADD_ROCKCHIP_SUB_DRIVER(vop2_platform_driver, CONFIG_ROCKCHIP_VOP2); + ADD_ROCKCHIP_SUB_DRIVER(rockchip_lvds_driver, + CONFIG_ROCKCHIP_LVDS); + ADD_ROCKCHIP_SUB_DRIVER(rockchip_dp_driver, +--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h +@@ -18,7 +18,7 @@ + + #define ROCKCHIP_MAX_FB_BUFFER 3 + #define ROCKCHIP_MAX_CONNECTOR 2 +-#define ROCKCHIP_MAX_CRTC 2 ++#define ROCKCHIP_MAX_CRTC 4 + + struct drm_device; + struct drm_connector; +@@ -31,6 +31,9 @@ struct rockchip_crtc_state { + int output_bpc; + int output_flags; + bool enable_afbc; ++ u32 bus_format; ++ u32 bus_flags; ++ int color_space; + }; + #define to_rockchip_crtc_state(s) \ + container_of(s, struct rockchip_crtc_state, base) +@@ -73,6 +76,7 @@ extern struct platform_driver rockchip_d + extern struct platform_driver rockchip_lvds_driver; + extern struct platform_driver vop_platform_driver; + extern struct platform_driver rk3066_hdmi_driver; ++extern struct platform_driver vop2_platform_driver; + + static inline struct rockchip_encoder *to_rockchip_encoder(struct drm_encoder *encoder) + { +--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c +@@ -134,4 +134,6 @@ void rockchip_drm_mode_config_init(struc + + dev->mode_config.funcs = &rockchip_drm_mode_config_funcs; + dev->mode_config.helper_private = &rockchip_mode_config_helpers; ++ ++ dev->mode_config.normalize_zpos = true; + } +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +@@ -54,9 +54,23 @@ struct vop_afbc { + struct vop_reg enable; + struct vop_reg win_sel; + struct vop_reg format; ++ struct vop_reg rb_swap; ++ struct vop_reg uv_swap; ++ struct vop_reg auto_gating_en; ++ struct vop_reg block_split_en; ++ struct vop_reg pic_vir_width; ++ struct vop_reg tile_num; + struct vop_reg hreg_block_split; ++ struct vop_reg pic_offset; + struct vop_reg pic_size; ++ struct vop_reg dsp_offset; ++ struct vop_reg transform_offset; + struct vop_reg hdr_ptr; ++ struct vop_reg half_block_en; ++ struct vop_reg xmirror; ++ struct vop_reg ymirror; ++ struct vop_reg rotate_270; ++ struct vop_reg rotate_90; + struct vop_reg rstn; + }; + diff --git a/target/linux/rockchip/patches-5.15/008-0031-v5.19-PCI-rockchip-dwc-Reset-core-at-driver-probe.patch b/target/linux/rockchip/patches-5.15/008-0031-v5.19-PCI-rockchip-dwc-Reset-core-at-driver-probe.patch new file mode 100644 index 000000000..fd380befd --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0031-v5.19-PCI-rockchip-dwc-Reset-core-at-driver-probe.patch @@ -0,0 +1,72 @@ +From 431e7d2eece5b906578926d15ee22a70504c364d Mon Sep 17 00:00:00 2001 +From: Peter Geis +Date: Fri, 29 Apr 2022 08:38:28 -0400 +Subject: [PATCH] PCI: rockchip-dwc: Reset core at driver probe + +The PCIe controller is in an unknown state at driver probe. This can +lead to undesireable effects when the driver attempts to configure the +controller. + +Prevent issues in the future by resetting the core during probe. + +Link: https://lore.kernel.org/r/20220429123832.2376381-3-pgwipeout@gmail.com +Tested-by: Nicolas Frattaroli +Signed-off-by: Peter Geis +Signed-off-by: Lorenzo Pieralisi +--- + drivers/pci/controller/dwc/pcie-dw-rockchip.c | 23 ++++++++----------- + 1 file changed, 10 insertions(+), 13 deletions(-) + +--- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c ++++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c +@@ -152,6 +152,11 @@ static int rockchip_pcie_resource_get(st + if (IS_ERR(rockchip->rst_gpio)) + return PTR_ERR(rockchip->rst_gpio); + ++ rockchip->rst = devm_reset_control_array_get_exclusive(&pdev->dev); ++ if (IS_ERR(rockchip->rst)) ++ return dev_err_probe(&pdev->dev, PTR_ERR(rockchip->rst), ++ "failed to get reset lines\n"); ++ + return 0; + } + +@@ -182,18 +187,6 @@ static void rockchip_pcie_phy_deinit(str + phy_power_off(rockchip->phy); + } + +-static int rockchip_pcie_reset_control_release(struct rockchip_pcie *rockchip) +-{ +- struct device *dev = rockchip->pci.dev; +- +- rockchip->rst = devm_reset_control_array_get_exclusive(dev); +- if (IS_ERR(rockchip->rst)) +- return dev_err_probe(dev, PTR_ERR(rockchip->rst), +- "failed to get reset lines\n"); +- +- return reset_control_deassert(rockchip->rst); +-} +- + static const struct dw_pcie_ops dw_pcie_ops = { + .link_up = rockchip_pcie_link_up, + .start_link = rockchip_pcie_start_link, +@@ -222,6 +215,10 @@ static int rockchip_pcie_probe(struct pl + if (ret) + return ret; + ++ ret = reset_control_assert(rockchip->rst); ++ if (ret) ++ return ret; ++ + /* DON'T MOVE ME: must be enable before PHY init */ + rockchip->vpcie3v3 = devm_regulator_get_optional(dev, "vpcie3v3"); + if (IS_ERR(rockchip->vpcie3v3)) { +@@ -241,7 +238,7 @@ static int rockchip_pcie_probe(struct pl + if (ret) + goto disable_regulator; + +- ret = rockchip_pcie_reset_control_release(rockchip); ++ ret = reset_control_deassert(rockchip->rst); + if (ret) + goto deinit_phy; + diff --git a/target/linux/rockchip/patches-5.15/008-0032-v5.19-PCI-rockchip-dwc-Add-legacy-interrupt-support.patch b/target/linux/rockchip/patches-5.15/008-0032-v5.19-PCI-rockchip-dwc-Add-legacy-interrupt-support.patch new file mode 100644 index 000000000..05b762ff5 --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0032-v5.19-PCI-rockchip-dwc-Add-legacy-interrupt-support.patch @@ -0,0 +1,163 @@ +From e8aae154df6121167e5b4f156cfc2402e651d2b1 Mon Sep 17 00:00:00 2001 +From: Peter Geis +Date: Fri, 29 Apr 2022 08:38:29 -0400 +Subject: [PATCH] PCI: rockchip-dwc: Add legacy interrupt support + +The legacy interrupts on the rk356x PCIe controller are handled by a +single muxed interrupt. Add IRQ domain support to the pcie-dw-rockchip +driver to support the virtual domain. + +Link: https://lore.kernel.org/r/20220429123832.2376381-4-pgwipeout@gmail.com +Signed-off-by: Peter Geis +Signed-off-by: Lorenzo Pieralisi +Reviewed-by: Marc Zyngier +--- + drivers/pci/controller/dwc/pcie-dw-rockchip.c | 96 ++++++++++++++++++- + 1 file changed, 94 insertions(+), 2 deletions(-) + +--- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c ++++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c +@@ -10,9 +10,12 @@ + + #include + #include ++#include ++#include + #include + #include + #include ++#include + #include + #include + #include +@@ -26,6 +29,7 @@ + */ + #define HIWORD_UPDATE(mask, val) (((mask) << 16) | (val)) + #define HIWORD_UPDATE_BIT(val) HIWORD_UPDATE(val, val) ++#define HIWORD_DISABLE_BIT(val) HIWORD_UPDATE(val, ~val) + + #define to_rockchip_pcie(x) dev_get_drvdata((x)->dev) + +@@ -36,10 +40,12 @@ + #define PCIE_LINKUP (PCIE_SMLH_LINKUP | PCIE_RDLH_LINKUP) + #define PCIE_L0S_ENTRY 0x11 + #define PCIE_CLIENT_GENERAL_CONTROL 0x0 ++#define PCIE_CLIENT_INTR_STATUS_LEGACY 0x8 ++#define PCIE_CLIENT_INTR_MASK_LEGACY 0x1c + #define PCIE_CLIENT_GENERAL_DEBUG 0x104 +-#define PCIE_CLIENT_HOT_RESET_CTRL 0x180 ++#define PCIE_CLIENT_HOT_RESET_CTRL 0x180 + #define PCIE_CLIENT_LTSSM_STATUS 0x300 +-#define PCIE_LTSSM_ENABLE_ENHANCE BIT(4) ++#define PCIE_LTSSM_ENABLE_ENHANCE BIT(4) + #define PCIE_LTSSM_STATUS_MASK GENMASK(5, 0) + + struct rockchip_pcie { +@@ -51,6 +57,7 @@ struct rockchip_pcie { + struct reset_control *rst; + struct gpio_desc *rst_gpio; + struct regulator *vpcie3v3; ++ struct irq_domain *irq_domain; + }; + + static int rockchip_pcie_readl_apb(struct rockchip_pcie *rockchip, +@@ -65,6 +72,78 @@ static void rockchip_pcie_writel_apb(str + writel_relaxed(val, rockchip->apb_base + reg); + } + ++static void rockchip_pcie_legacy_int_handler(struct irq_desc *desc) ++{ ++ struct irq_chip *chip = irq_desc_get_chip(desc); ++ struct rockchip_pcie *rockchip = irq_desc_get_handler_data(desc); ++ unsigned long reg, hwirq; ++ ++ chained_irq_enter(chip, desc); ++ ++ reg = rockchip_pcie_readl_apb(rockchip, PCIE_CLIENT_INTR_STATUS_LEGACY); ++ ++ for_each_set_bit(hwirq, ®, 4) ++ generic_handle_domain_irq(rockchip->irq_domain, hwirq); ++ ++ chained_irq_exit(chip, desc); ++} ++ ++static void rockchip_intx_mask(struct irq_data *data) ++{ ++ rockchip_pcie_writel_apb(irq_data_get_irq_chip_data(data), ++ HIWORD_UPDATE_BIT(BIT(data->hwirq)), ++ PCIE_CLIENT_INTR_MASK_LEGACY); ++}; ++ ++static void rockchip_intx_unmask(struct irq_data *data) ++{ ++ rockchip_pcie_writel_apb(irq_data_get_irq_chip_data(data), ++ HIWORD_DISABLE_BIT(BIT(data->hwirq)), ++ PCIE_CLIENT_INTR_MASK_LEGACY); ++}; ++ ++static struct irq_chip rockchip_intx_irq_chip = { ++ .name = "INTx", ++ .irq_mask = rockchip_intx_mask, ++ .irq_unmask = rockchip_intx_unmask, ++ .flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND, ++}; ++ ++static int rockchip_pcie_intx_map(struct irq_domain *domain, unsigned int irq, ++ irq_hw_number_t hwirq) ++{ ++ irq_set_chip_and_handler(irq, &rockchip_intx_irq_chip, handle_level_irq); ++ irq_set_chip_data(irq, domain->host_data); ++ ++ return 0; ++} ++ ++static const struct irq_domain_ops intx_domain_ops = { ++ .map = rockchip_pcie_intx_map, ++}; ++ ++static int rockchip_pcie_init_irq_domain(struct rockchip_pcie *rockchip) ++{ ++ struct device *dev = rockchip->pci.dev; ++ struct device_node *intc; ++ ++ intc = of_get_child_by_name(dev->of_node, "legacy-interrupt-controller"); ++ if (!intc) { ++ dev_err(dev, "missing child interrupt-controller node\n"); ++ return -EINVAL; ++ } ++ ++ rockchip->irq_domain = irq_domain_add_linear(intc, PCI_NUM_INTX, ++ &intx_domain_ops, rockchip); ++ of_node_put(intc); ++ if (!rockchip->irq_domain) { ++ dev_err(dev, "failed to get a INTx IRQ domain\n"); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ + static void rockchip_pcie_enable_ltssm(struct rockchip_pcie *rockchip) + { + rockchip_pcie_writel_apb(rockchip, PCIE_CLIENT_ENABLE_LTSSM, +@@ -111,7 +190,20 @@ static int rockchip_pcie_host_init(struc + { + struct dw_pcie *pci = to_dw_pcie_from_pp(pp); + struct rockchip_pcie *rockchip = to_rockchip_pcie(pci); ++ struct device *dev = rockchip->pci.dev; + u32 val = HIWORD_UPDATE_BIT(PCIE_LTSSM_ENABLE_ENHANCE); ++ int irq, ret; ++ ++ irq = of_irq_get_byname(dev->of_node, "legacy"); ++ if (irq < 0) ++ return irq; ++ ++ ret = rockchip_pcie_init_irq_domain(rockchip); ++ if (ret < 0) ++ dev_err(dev, "failed to init irq domain\n"); ++ ++ irq_set_chained_handler_and_data(irq, rockchip_pcie_legacy_int_handler, ++ rockchip); + + /* LTSSM enable control mode */ + rockchip_pcie_writel_apb(rockchip, val, PCIE_CLIENT_HOT_RESET_CTRL); diff --git a/target/linux/rockchip/patches-5.15/008-0033-v6.0-drm-rockchip-vop2-unlock-on-error-path-in.patch b/target/linux/rockchip/patches-5.15/008-0033-v6.0-drm-rockchip-vop2-unlock-on-error-path-in.patch new file mode 100644 index 000000000..bf17aa7ff --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0033-v6.0-drm-rockchip-vop2-unlock-on-error-path-in.patch @@ -0,0 +1,27 @@ +From 98526c5bbe3267d447ddd076b685439e3e1396c6 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Mon, 9 May 2022 12:05:05 +0300 +Subject: [PATCH] drm/rockchip: vop2: unlock on error path in + vop2_crtc_atomic_enable() + +This error path needs an unlock before returning. + +Fixes: 604be85547ce ("drm/rockchip: Add VOP2 driver") +Signed-off-by: Dan Carpenter +Acked-by: Sascha Hauer +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/YnjZQRV9lpub2ET8@kili +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +@@ -1524,6 +1524,7 @@ static void vop2_crtc_atomic_enable(stru + if (ret < 0) { + drm_err(vop2->drm, "failed to enable dclk for video port%d - %d\n", + vp->id, ret); ++ vop2_unlock(vop2); + return; + } + diff --git a/target/linux/rockchip/patches-5.15/008-0034-v6.0-media-hantro-Add-support-for-RK356x-encoder.patch b/target/linux/rockchip/patches-5.15/008-0034-v6.0-media-hantro-Add-support-for-RK356x-encoder.patch new file mode 100644 index 000000000..33b2544bd --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0034-v6.0-media-hantro-Add-support-for-RK356x-encoder.patch @@ -0,0 +1,96 @@ +From 6f1ae821a6c4aa9d5b8f437b27ec86fb569219fd Mon Sep 17 00:00:00 2001 +From: Nicolas Frattaroli +Date: Sun, 12 Jun 2022 16:53:45 +0100 +Subject: [PATCH] media: hantro: Add support for RK356x encoder + +The RK3566 and RK3568 SoCs come with a small Hantro instance which is +solely dedicated to encoding. This patch adds the necessary structs to +the Hantro driver to allow the JPEG encoder of it to function. + +Through some sleuthing through the vendor's MPP source code and after +closer inspection of the TRM, it was determined that the hardware likely +supports VP8 and H.264 as well. + +Tested with the following GStreamer command: + +gst-launch-1.0 videotestsrc ! v4l2jpegenc ! matroskamux ! \ + filesink location=foo.mkv + +Signed-off-by: Nicolas Frattaroli +Reviewed-by: Ezequiel Garcia +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +--- + drivers/staging/media/hantro/hantro_drv.c | 1 + + drivers/staging/media/hantro/hantro_hw.h | 1 + + .../staging/media/hantro/rockchip_vpu_hw.c | 25 +++++++++++++++++++ + 3 files changed, 27 insertions(+) + +--- a/drivers/staging/media/hantro/hantro_drv.c ++++ b/drivers/staging/media/hantro/hantro_drv.c +@@ -588,6 +588,7 @@ static const struct of_device_id of_hant + { .compatible = "rockchip,rk3288-vpu", .data = &rk3288_vpu_variant, }, + { .compatible = "rockchip,rk3328-vpu", .data = &rk3328_vpu_variant, }, + { .compatible = "rockchip,rk3399-vpu", .data = &rk3399_vpu_variant, }, ++ { .compatible = "rockchip,rk3568-vepu", .data = &rk3568_vepu_variant, }, + { .compatible = "rockchip,rk3568-vpu", .data = &rk3568_vpu_variant, }, + #endif + #ifdef CONFIG_VIDEO_HANTRO_IMX8M +--- a/drivers/staging/media/hantro/hantro_hw.h ++++ b/drivers/staging/media/hantro/hantro_hw.h +@@ -215,6 +215,7 @@ extern const struct hantro_variant rk306 + extern const struct hantro_variant rk3288_vpu_variant; + extern const struct hantro_variant rk3328_vpu_variant; + extern const struct hantro_variant rk3399_vpu_variant; ++extern const struct hantro_variant rk3568_vepu_variant; + extern const struct hantro_variant rk3568_vpu_variant; + extern const struct hantro_variant sama5d4_vdec_variant; + +--- a/drivers/staging/media/hantro/rockchip_vpu_hw.c ++++ b/drivers/staging/media/hantro/rockchip_vpu_hw.c +@@ -423,6 +423,14 @@ static const struct hantro_codec_ops rk3 + }, + }; + ++static const struct hantro_codec_ops rk3568_vepu_codec_ops[] = { ++ [HANTRO_MODE_JPEG_ENC] = { ++ .run = rockchip_vpu2_jpeg_enc_run, ++ .reset = rockchip_vpu2_enc_reset, ++ .done = rockchip_vpu2_jpeg_enc_done, ++ }, ++}; ++ + /* + * VPU variant. + */ +@@ -445,6 +453,10 @@ static const struct hantro_irq rockchip_ + { "vdpu", rockchip_vpu2_vdpu_irq }, + }; + ++static const struct hantro_irq rk3568_vepu_irqs[] = { ++ { "vepu", rockchip_vpu2_vepu_irq }, ++}; ++ + static const char * const rk3066_vpu_clk_names[] = { + "aclk_vdpu", "hclk_vdpu", + "aclk_vepu", "hclk_vepu" +@@ -549,6 +561,19 @@ const struct hantro_variant rk3399_vpu_v + .init = rockchip_vpu_hw_init, + .clk_names = rockchip_vpu_clk_names, + .num_clocks = ARRAY_SIZE(rockchip_vpu_clk_names) ++}; ++ ++const struct hantro_variant rk3568_vepu_variant = { ++ .enc_offset = 0x0, ++ .enc_fmts = rockchip_vpu_enc_fmts, ++ .num_enc_fmts = ARRAY_SIZE(rockchip_vpu_enc_fmts), ++ .codec = HANTRO_JPEG_ENCODER, ++ .codec_ops = rk3568_vepu_codec_ops, ++ .irqs = rk3568_vepu_irqs, ++ .num_irqs = ARRAY_SIZE(rk3568_vepu_irqs), ++ .init = rockchip_vpu_hw_init, ++ .clk_names = rockchip_vpu_clk_names, ++ .num_clocks = ARRAY_SIZE(rockchip_vpu_clk_names) + }; + + const struct hantro_variant rk3568_vpu_variant = { diff --git a/target/linux/rockchip/patches-5.15/008-0035-v6.0-phy-rockchip-inno-usb2-Ignore-OTG-IRQs-in-host-mode.patch b/target/linux/rockchip/patches-5.15/008-0035-v6.0-phy-rockchip-inno-usb2-Ignore-OTG-IRQs-in-host-mode.patch new file mode 100644 index 000000000..b850bbcf5 --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0035-v6.0-phy-rockchip-inno-usb2-Ignore-OTG-IRQs-in-host-mode.patch @@ -0,0 +1,36 @@ +From fd7d47484125c7d04578de9294faa7fec6e5df0a Mon Sep 17 00:00:00 2001 +From: Samuel Holland +Date: Fri, 8 Jul 2022 01:14:34 -0500 +Subject: [PATCH] phy: rockchip-inno-usb2: Ignore OTG IRQs in host mode + +When the OTG port is fixed to host mode, the driver does not request its +IRQs, nor does it enable those IRQs in hardware. Similarly, the driver +should ignore the OTG port IRQs when handling the shared interrupt. + +Otherwise, it would update the extcon based on an ID pin which may be in +an undefined state, or try to queue a uninitialized work item. + +Fixes: 6a98df08ccd5 ("phy: rockchip-inno-usb2: Fix muxed interrupt support") +Reported-by: Frank Wunderlich +Signed-off-by: Samuel Holland +Tested-by: Peter Geis +Tested-by: Frank Wunderlich +Link: https://lore.kernel.org/r/20220708061434.38115-1-samuel@sholland.org +Signed-off-by: Vinod Koul +--- + drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +@@ -986,7 +986,9 @@ static irqreturn_t rockchip_usb2phy_irq( + + switch (rport->port_id) { + case USB2PHY_PORT_OTG: +- ret |= rockchip_usb2phy_otg_mux_irq(irq, rport); ++ if (rport->mode != USB_DR_MODE_HOST && ++ rport->mode != USB_DR_MODE_UNKNOWN) ++ ret |= rockchip_usb2phy_otg_mux_irq(irq, rport); + break; + case USB2PHY_PORT_HOST: + ret |= rockchip_usb2phy_linestate_irq(irq, rport); diff --git a/target/linux/rockchip/patches-5.15/008-0036-v6.0-media-hantro-Fix-RK3399-H.264-format-advertising.patch b/target/linux/rockchip/patches-5.15/008-0036-v6.0-media-hantro-Fix-RK3399-H.264-format-advertising.patch new file mode 100644 index 000000000..22e33fca3 --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0036-v6.0-media-hantro-Fix-RK3399-H.264-format-advertising.patch @@ -0,0 +1,126 @@ +From 177d841fa19542eb35aa5ec9579c4abb989c9255 Mon Sep 17 00:00:00 2001 +From: Ezequiel Garcia +Date: Wed, 29 Jun 2022 20:56:23 +0100 +Subject: [PATCH] media: hantro: Fix RK3399 H.264 format advertising + +Commit 1f82f2df523cb ("media: hantro: Enable H.264 on Rockchip VDPU2") +enabled H.264 on some SoCs with VDPU2 cores. This had the side-effect +of exposing H.264 coded format as supported on RK3399. + +Fix this and clarify how the codec is explicitly disabled on RK3399 on +this driver. + +Fixes: 1f82f2df523cb ("media: hantro: Enable H.264 on Rockchip VDPU2") +Signed-off-by: Ezequiel Garcia +Tested-by: Nicolas Dufresne +Reviewed-by: Nicolas Dufresne +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +--- + .../staging/media/hantro/rockchip_vpu_hw.c | 60 ++++++++++++++++--- + 1 file changed, 53 insertions(+), 7 deletions(-) + +--- a/drivers/staging/media/hantro/rockchip_vpu_hw.c ++++ b/drivers/staging/media/hantro/rockchip_vpu_hw.c +@@ -158,7 +158,7 @@ static const struct hantro_fmt rk3288_vp + }, + }; + +-static const struct hantro_fmt rk3399_vpu_dec_fmts[] = { ++static const struct hantro_fmt rockchip_vdpu2_dec_fmts[] = { + { + .fourcc = V4L2_PIX_FMT_NV12, + .codec_mode = HANTRO_MODE_NONE, +@@ -204,6 +204,47 @@ static const struct hantro_fmt rk3399_vp + }, + }; + ++static const struct hantro_fmt rk3399_vpu_dec_fmts[] = { ++ { ++ .fourcc = V4L2_PIX_FMT_NV12, ++ .codec_mode = HANTRO_MODE_NONE, ++ .frmsize = { ++ .min_width = FMT_MIN_WIDTH, ++ .max_width = FMT_FHD_WIDTH, ++ .step_width = MB_DIM, ++ .min_height = FMT_MIN_HEIGHT, ++ .max_height = FMT_FHD_HEIGHT, ++ .step_height = MB_DIM, ++ }, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_MPEG2_SLICE, ++ .codec_mode = HANTRO_MODE_MPEG2_DEC, ++ .max_depth = 2, ++ .frmsize = { ++ .min_width = FMT_MIN_WIDTH, ++ .max_width = FMT_FHD_WIDTH, ++ .step_width = MB_DIM, ++ .min_height = FMT_MIN_HEIGHT, ++ .max_height = FMT_FHD_HEIGHT, ++ .step_height = MB_DIM, ++ }, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_VP8_FRAME, ++ .codec_mode = HANTRO_MODE_VP8_DEC, ++ .max_depth = 2, ++ .frmsize = { ++ .min_width = FMT_MIN_WIDTH, ++ .max_width = FMT_UHD_WIDTH, ++ .step_width = MB_DIM, ++ .min_height = FMT_MIN_HEIGHT, ++ .max_height = FMT_UHD_HEIGHT, ++ .step_height = MB_DIM, ++ }, ++ }, ++}; ++ + static irqreturn_t rockchip_vpu1_vepu_irq(int irq, void *dev_id) + { + struct hantro_dev *vpu = dev_id; +@@ -534,8 +575,8 @@ const struct hantro_variant rk3288_vpu_v + + const struct hantro_variant rk3328_vpu_variant = { + .dec_offset = 0x400, +- .dec_fmts = rk3399_vpu_dec_fmts, +- .num_dec_fmts = ARRAY_SIZE(rk3399_vpu_dec_fmts), ++ .dec_fmts = rockchip_vdpu2_dec_fmts, ++ .num_dec_fmts = ARRAY_SIZE(rockchip_vdpu2_dec_fmts), + .codec = HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER | + HANTRO_H264_DECODER, + .codec_ops = rk3399_vpu_codec_ops, +@@ -546,6 +587,11 @@ const struct hantro_variant rk3328_vpu_v + .num_clocks = ARRAY_SIZE(rockchip_vpu_clk_names), + }; + ++/* ++ * H.264 decoding explicitly disabled in RK3399. ++ * This ensures userspace applications use the Rockchip VDEC core, ++ * which has better performance. ++ */ + const struct hantro_variant rk3399_vpu_variant = { + .enc_offset = 0x0, + .enc_fmts = rockchip_vpu_enc_fmts, +@@ -578,8 +624,8 @@ const struct hantro_variant rk3568_vepu_ + + const struct hantro_variant rk3568_vpu_variant = { + .dec_offset = 0x400, +- .dec_fmts = rk3399_vpu_dec_fmts, +- .num_dec_fmts = ARRAY_SIZE(rk3399_vpu_dec_fmts), ++ .dec_fmts = rockchip_vdpu2_dec_fmts, ++ .num_dec_fmts = ARRAY_SIZE(rockchip_vdpu2_dec_fmts), + .codec = HANTRO_MPEG2_DECODER | + HANTRO_VP8_DECODER | HANTRO_H264_DECODER, + .codec_ops = rk3399_vpu_codec_ops, +@@ -595,8 +641,8 @@ const struct hantro_variant px30_vpu_var + .enc_fmts = rockchip_vpu_enc_fmts, + .num_enc_fmts = ARRAY_SIZE(rockchip_vpu_enc_fmts), + .dec_offset = 0x400, +- .dec_fmts = rk3399_vpu_dec_fmts, +- .num_dec_fmts = ARRAY_SIZE(rk3399_vpu_dec_fmts), ++ .dec_fmts = rockchip_vdpu2_dec_fmts, ++ .num_dec_fmts = ARRAY_SIZE(rockchip_vdpu2_dec_fmts), + .codec = HANTRO_JPEG_ENCODER | HANTRO_MPEG2_DECODER | + HANTRO_VP8_DECODER | HANTRO_H264_DECODER, + .codec_ops = rk3399_vpu_codec_ops, diff --git a/target/linux/rockchip/patches-5.15/008-0037-v6.0-phy-rockchip-inno-usb2-Prevent-incorrect-error-on-probe.patch b/target/linux/rockchip/patches-5.15/008-0037-v6.0-phy-rockchip-inno-usb2-Prevent-incorrect-error-on-probe.patch new file mode 100644 index 000000000..f65056fe2 --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0037-v6.0-phy-rockchip-inno-usb2-Prevent-incorrect-error-on-probe.patch @@ -0,0 +1,27 @@ +From b113e55913e7f7f031d6cbf9d7b585c6b112f55a Mon Sep 17 00:00:00 2001 +From: Peter Geis +Date: Sat, 25 Jun 2022 17:27:11 -0400 +Subject: [PATCH] phy: rockchip-inno-usb2: Prevent incorrect error on probe + +If a phy supply is designated but isn't available at probe time, an +EPROBE_DEFER is returned. Use dev_err_probe to prevent this from +incorrectly printing during boot. + +Signed-off-by: Peter Geis +Link: https://lore.kernel.org/r/20220625212711.558495-1-pgwipeout@gmail.com +Signed-off-by: Vinod Koul +--- + drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +@@ -1293,7 +1293,7 @@ static int rockchip_usb2phy_probe(struct + + phy = devm_phy_create(dev, child_np, &rockchip_usb2phy_ops); + if (IS_ERR(phy)) { +- dev_err(dev, "failed to create phy\n"); ++ dev_err_probe(dev, PTR_ERR(phy), "failed to create phy\n"); + ret = PTR_ERR(phy); + goto put_child; + } diff --git a/target/linux/rockchip/patches-5.15/008-0038-v6.0-phy-rockchip-inno-usb2-Sync-initial-otg-state.patch b/target/linux/rockchip/patches-5.15/008-0038-v6.0-phy-rockchip-inno-usb2-Sync-initial-otg-state.patch new file mode 100644 index 000000000..666c31539 --- /dev/null +++ b/target/linux/rockchip/patches-5.15/008-0038-v6.0-phy-rockchip-inno-usb2-Sync-initial-otg-state.patch @@ -0,0 +1,33 @@ +From 8dc60f8da22fdbaa1fafcfb5ff6d24bc9eff56aa Mon Sep 17 00:00:00 2001 +From: Peter Geis +Date: Tue, 21 Jun 2022 20:31:40 -0400 +Subject: [PATCH] phy: rockchip-inno-usb2: Sync initial otg state + +The initial otg state for the phy defaults to device mode. The actual +state isn't detected until an ID IRQ fires. Fix this by syncing the ID +state during initialization. + +Fixes: 51a9b2c03dd3 ("phy: rockchip-inno-usb2: Handle ID IRQ") +Signed-off-by: Peter Geis +Reviewed-by: Samuel Holland +Link: https://lore.kernel.org/r/20220622003140.30365-1-pgwipeout@gmail.com +Signed-off-by: Vinod Koul +--- + drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +@@ -1172,6 +1172,12 @@ static int rockchip_usb2phy_otg_port_ini + EXTCON_USB_HOST, &rport->event_nb); + if (ret) + dev_err(rphy->dev, "register USB HOST notifier failed\n"); ++ ++ if (!of_property_read_bool(rphy->dev->of_node, "extcon")) { ++ /* do initial sync of usb state */ ++ ret = property_enabled(rphy->grf, &rport->port_cfg->utmi_id); ++ extcon_set_state_sync(rphy->edev, EXTCON_USB_HOST, !ret); ++ } + } + + out: diff --git a/target/linux/rockchip/patches-5.15/009-v6.0-arm64-enable-THP_SWAP-for-arm64.patch b/target/linux/rockchip/patches-5.15/009-v6.0-arm64-enable-THP_SWAP-for-arm64.patch new file mode 100644 index 000000000..036a87b4f --- /dev/null +++ b/target/linux/rockchip/patches-5.15/009-v6.0-arm64-enable-THP_SWAP-for-arm64.patch @@ -0,0 +1,123 @@ +From d0637c505f8a1d8c4088642f1f3e9e3b22da14f6 Mon Sep 17 00:00:00 2001 +From: Barry Song +Date: Wed, 20 Jul 2022 21:37:37 +1200 +Subject: [PATCH] arm64: enable THP_SWAP for arm64 + +THP_SWAP has been proven to improve the swap throughput significantly +on x86_64 according to commit bd4c82c22c367e ("mm, THP, swap: delay +splitting THP after swapped out"). +As long as arm64 uses 4K page size, it is quite similar with x86_64 +by having 2MB PMD THP. THP_SWAP is architecture-independent, thus, +enabling it on arm64 will benefit arm64 as well. +A corner case is that MTE has an assumption that only base pages +can be swapped. We won't enable THP_SWAP for ARM64 hardware with +MTE support until MTE is reworked to coexist with THP_SWAP. + +A micro-benchmark is written to measure thp swapout throughput as +below, + + unsigned long long tv_to_ms(struct timeval tv) + { + return tv.tv_sec * 1000 + tv.tv_usec / 1000; + } + + main() + { + struct timeval tv_b, tv_e;; + #define SIZE 400*1024*1024 + volatile void *p = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (!p) { + perror("fail to get memory"); + exit(-1); + } + + madvise(p, SIZE, MADV_HUGEPAGE); + memset(p, 0x11, SIZE); /* write to get mem */ + + gettimeofday(&tv_b, NULL); + madvise(p, SIZE, MADV_PAGEOUT); + gettimeofday(&tv_e, NULL); + + printf("swp out bandwidth: %ld bytes/ms\n", + SIZE/(tv_to_ms(tv_e) - tv_to_ms(tv_b))); + } + +Testing is done on rk3568 64bit Quad Core Cortex-A55 platform - +ROCK 3A. +thp swp throughput w/o patch: 2734bytes/ms (mean of 10 tests) +thp swp throughput w/ patch: 3331bytes/ms (mean of 10 tests) + +Cc: "Huang, Ying" +Cc: Minchan Kim +Cc: Johannes Weiner +Cc: Hugh Dickins +Cc: Andrea Arcangeli +Cc: Steven Price +Cc: Yang Shi +Reviewed-by: Anshuman Khandual +Signed-off-by: Barry Song +Link: https://lore.kernel.org/r/20220720093737.133375-1-21cnbao@gmail.com +Signed-off-by: Will Deacon +--- + arch/arm64/Kconfig | 1 + + arch/arm64/include/asm/pgtable.h | 6 ++++++ + include/linux/huge_mm.h | 12 ++++++++++++ + mm/swap_slots.c | 2 +- + 4 files changed, 20 insertions(+), 1 deletion(-) + +--- a/arch/arm64/Kconfig ++++ b/arch/arm64/Kconfig +@@ -95,6 +95,7 @@ config ARM64 + select ARCH_WANT_HUGE_PMD_SHARE if ARM64_4K_PAGES || (ARM64_16K_PAGES && !ARM64_VA_BITS_36) + select ARCH_WANT_LD_ORPHAN_WARN + select ARCH_WANTS_NO_INSTR ++ select ARCH_WANTS_THP_SWAP if ARM64_4K_PAGES + select ARCH_HAS_UBSAN_SANITIZE_ALL + select ARM_AMBA + select ARM_ARCH_TIMER +--- a/arch/arm64/include/asm/pgtable.h ++++ b/arch/arm64/include/asm/pgtable.h +@@ -44,6 +44,12 @@ + __flush_tlb_range(vma, addr, end, PUD_SIZE, false, 1) + #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ + ++static inline bool arch_thp_swp_supported(void) ++{ ++ return !system_supports_mte(); ++} ++#define arch_thp_swp_supported arch_thp_swp_supported ++ + /* + * Outside of a few very special situations (e.g. hibernation), we always + * use broadcast TLB invalidation instructions, therefore a spurious page +--- a/include/linux/huge_mm.h ++++ b/include/linux/huge_mm.h +@@ -495,4 +495,16 @@ static inline unsigned long thp_size(str + return PAGE_SIZE << thp_order(page); + } + ++/* ++ * archs that select ARCH_WANTS_THP_SWAP but don't support THP_SWP due to ++ * limitations in the implementation like arm64 MTE can override this to ++ * false ++ */ ++#ifndef arch_thp_swp_supported ++static inline bool arch_thp_swp_supported(void) ++{ ++ return true; ++} ++#endif ++ + #endif /* _LINUX_HUGE_MM_H */ +--- a/mm/swap_slots.c ++++ b/mm/swap_slots.c +@@ -308,7 +308,7 @@ swp_entry_t get_swap_page(struct page *p + entry.val = 0; + + if (PageTransHuge(page)) { +- if (IS_ENABLED(CONFIG_THP_SWAP)) ++ if (IS_ENABLED(CONFIG_THP_SWAP) && arch_thp_swp_supported()) + get_swap_pages(1, &entry, HPAGE_PMD_NR); + goto out; + } diff --git a/target/linux/rockchip/patches-5.15/108-phy-rockchip-Support-PCIe-v3.patch b/target/linux/rockchip/patches-5.15/108-phy-rockchip-Support-PCIe-v3.patch new file mode 100644 index 000000000..e0080d379 --- /dev/null +++ b/target/linux/rockchip/patches-5.15/108-phy-rockchip-Support-PCIe-v3.patch @@ -0,0 +1,106 @@ +From: Frank Wunderlich +To: linux-rockchip@lists.infradead.org +Cc: Frank Wunderlich , + Kishon Vijay Abraham I , + Vinod Koul , Rob Herring , + Krzysztof Kozlowski , + Heiko Stuebner , + Philipp Zabel , + Johan Jonker , + Yifeng Zhao , + Peter Geis , + Michael Riesch , + Liang Chen , Simon Xue , + Shawn Lin , + linux-phy@lists.infradead.org, devicetree@vger.kernel.org, + linux-arm-kernel@lists.infradead.org, + linux-kernel@vger.kernel.org +Subject: [PATCH v4 3/5] phy: rockchip: Support PCIe v3 +Date: Sun, 19 Jun 2022 10:26:03 +0200 [thread overview] +Message-ID: <20220619082605.7935-4-linux@fw-web.de> (raw) +In-Reply-To: <20220619082605.7935-1-linux@fw-web.de> + +From: Shawn Lin + +RK3568 supports PCIe v3 using not Combphy like PCIe v2 on rk3566. +It use a dedicated PCIe-phy. Add support for this. + +Initial support by Shawn Lin, modifications by Peter Geis and Frank +Wunderlich. + +Add data-lanes property for splitting pcie-lanes across controllers. + +The data-lanes is an array where x=0 means lane is disabled and x > 0 +means controller x is assigned to phy lane. + +Signed-off-by: Shawn Lin +Suggested-by: Peter Geis +Signed-off-by: Frank Wunderlich +--- +v4: +- change u8 lane-map to u32 data-lanes + +v3: +- change dt-binding include +- change reset to devm_reset_control_get_optional_exclusive + exit on error and lower severity of message if unset +- fix from peter: disable reg-write for phy-mode in rockchip_p3phy_probe +- move bifurcation/lane-map support from PCIe to phy driver + +v2: +- move dt-bindings header into separate patch +- use BIT-macro +- make constants better readable +- use dev_err instead of pr_* +- change dt-binding include due to renaming (phy-snps-pcie3.h => phy-rockchip-pcie3.h) +- use exclusive variant of devm_reset_control_get{,_exclusive} +- fix semicolon.cocci warnings reported by kernel test robot + +--- +driver was taken from linux 5.10 based on in +https://github.com/JeffyCN/mirrors +which now has disappeared + +Update phy-rockchip-snps-pcie3.c + +Fix messages for data-lanes + +Update phy-rockchip-snps-pcie3.c + +Fix comment for data-lanes +--- + drivers/phy/rockchip/Kconfig | 9 + + drivers/phy/rockchip/Makefile | 1 + + .../phy/rockchip/phy-rockchip-snps-pcie3.c | 317 ++++++++++++++++++ + include/linux/phy/pcie.h | 12 + + 4 files changed, 339 insertions(+) + create mode 100644 drivers/phy/rockchip/phy-rockchip-snps-pcie3.c + create mode 100644 include/linux/phy/pcie.h + +--- a/drivers/phy/rockchip/Kconfig ++++ b/drivers/phy/rockchip/Kconfig +@@ -83,6 +83,15 @@ config PHY_ROCKCHIP_PCIE + help + Enable this to support the Rockchip PCIe PHY. + ++config PHY_ROCKCHIP_SNPS_PCIE3 ++ tristate "Rockchip Snps PCIe3 PHY Driver" ++ depends on (ARCH_ROCKCHIP && OF) || COMPILE_TEST ++ depends on HAS_IOMEM ++ select GENERIC_PHY ++ select MFD_SYSCON ++ help ++ Enable this to support the Rockchip snps PCIe3 PHY. ++ + config PHY_ROCKCHIP_TYPEC + tristate "Rockchip TYPEC PHY Driver" + depends on OF && (ARCH_ROCKCHIP || COMPILE_TEST) +--- a/drivers/phy/rockchip/Makefile ++++ b/drivers/phy/rockchip/Makefile +@@ -8,5 +8,6 @@ obj-$(CONFIG_PHY_ROCKCHIP_INNO_HDMI) += + obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2) += phy-rockchip-inno-usb2.o + obj-$(CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY) += phy-rockchip-naneng-combphy.o + obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-rockchip-pcie.o ++obj-$(CONFIG_PHY_ROCKCHIP_SNPS_PCIE3) += phy-rockchip-snps-pcie3.o + obj-$(CONFIG_PHY_ROCKCHIP_TYPEC) += phy-rockchip-typec.o + obj-$(CONFIG_PHY_ROCKCHIP_USB) += phy-rockchip-usb.o diff --git a/target/linux/rockchip/patches-5.15/109-arm64-dts-rockchip-rk3568-Add-PCIe-v3-nodes.patch b/target/linux/rockchip/patches-5.15/109-arm64-dts-rockchip-rk3568-Add-PCIe-v3-nodes.patch new file mode 100644 index 000000000..6513c17c3 --- /dev/null +++ b/target/linux/rockchip/patches-5.15/109-arm64-dts-rockchip-rk3568-Add-PCIe-v3-nodes.patch @@ -0,0 +1,174 @@ +From: Frank Wunderlich +To: linux-rockchip@lists.infradead.org +Cc: Frank Wunderlich , + Kishon Vijay Abraham I , + Vinod Koul , Rob Herring , + Krzysztof Kozlowski , + Heiko Stuebner , + Philipp Zabel , + Johan Jonker , + Yifeng Zhao , + Peter Geis , + Michael Riesch , + Liang Chen , Simon Xue , + Shawn Lin , + linux-phy@lists.infradead.org, devicetree@vger.kernel.org, + linux-arm-kernel@lists.infradead.org, + linux-kernel@vger.kernel.org +Subject: [PATCH v4 4/5] arm64: dts: rockchip: rk3568: Add PCIe v3 nodes +Date: Sun, 19 Jun 2022 10:26:04 +0200 [thread overview] +Message-ID: <20220619082605.7935-5-linux@fw-web.de> (raw) +In-Reply-To: <20220619082605.7935-1-linux@fw-web.de> + +From: Frank Wunderlich + +Add nodes to rk356x devicetree to support PCIe v3. + +Co-developed-by: Peter Geis +Signed-off-by: Frank Wunderlich +--- +v4: +- update pcie3 reg/ranges + +v3: +- fix from Peter: change bus-range and msi-map, msi-map needs + to start from 0x0 + +v2: +- change to compatible with soc-part +- change rockchip,bifurcation to vendor unspecific bifurcation +--- + arch/arm64/boot/dts/rockchip/rk3568.dtsi | 122 +++++++++++++++++++++++ + 1 file changed, 122 insertions(+) + +--- a/arch/arm64/boot/dts/rockchip/rk3568.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3568.dtsi +@@ -42,6 +42,128 @@ + reg = <0x0 0xfe190200 0x0 0x20>; + }; + ++ pcie30_phy_grf: syscon@fdcb8000 { ++ compatible = "rockchip,rk3568-pcie3-phy-grf", "syscon"; ++ reg = <0x0 0xfdcb8000 0x0 0x10000>; ++ }; ++ ++ pcie30phy: phy@fe8c0000 { ++ compatible = "rockchip,rk3568-pcie3-phy"; ++ reg = <0x0 0xfe8c0000 0x0 0x20000>; ++ #phy-cells = <0>; ++ clocks = <&pmucru CLK_PCIE30PHY_REF_M>, <&pmucru CLK_PCIE30PHY_REF_N>, ++ <&cru PCLK_PCIE30PHY>; ++ clock-names = "refclk_m", "refclk_n", "pclk"; ++ resets = <&cru SRST_PCIE30PHY>; ++ reset-names = "phy"; ++ rockchip,phy-grf = <&pcie30_phy_grf>; ++ status = "disabled"; ++ }; ++ ++ pcie3x1: pcie@fe270000 { ++ compatible = "rockchip,rk3568-pcie"; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ bus-range = <0x0 0xf>; ++ clocks = <&cru ACLK_PCIE30X1_MST>, <&cru ACLK_PCIE30X1_SLV>, ++ <&cru ACLK_PCIE30X1_DBI>, <&cru PCLK_PCIE30X1>, ++ <&cru CLK_PCIE30X1_AUX_NDFT>; ++ clock-names = "aclk_mst", "aclk_slv", ++ "aclk_dbi", "pclk", "aux"; ++ device_type = "pci"; ++ interrupts = , ++ , ++ , ++ , ++ ; ++ interrupt-names = "sys", "pmc", "msg", "legacy", "err"; ++ #interrupt-cells = <1>; ++ interrupt-map-mask = <0 0 0 7>; ++ interrupt-map = <0 0 0 1 &pcie3x1_intc 0>, ++ <0 0 0 2 &pcie3x1_intc 1>, ++ <0 0 0 3 &pcie3x1_intc 2>, ++ <0 0 0 4 &pcie3x1_intc 3>; ++ linux,pci-domain = <1>; ++ num-ib-windows = <6>; ++ num-ob-windows = <2>; ++ max-link-speed = <3>; ++ msi-map = <0x0 &gic 0x1000 0x1000>; ++ num-lanes = <1>; ++ phys = <&pcie30phy>; ++ phy-names = "pcie-phy"; ++ power-domains = <&power RK3568_PD_PIPE>; ++ reg = <0x3 0xc0400000 0x0 0x00400000>, ++ <0x0 0xfe270000 0x0 0x00010000>, ++ <0x3 0x7f000000 0x0 0x01000000>; ++ ranges = <0x01000000 0x0 0x3ef00000 0x3 0x7ef00000 0x0 0x00100000>, ++ <0x02000000 0x0 0x00000000 0x3 0x40000000 0x0 0x3ef00000>; ++ reg-names = "dbi", "apb", "config"; ++ resets = <&cru SRST_PCIE30X1_POWERUP>; ++ reset-names = "pipe"; ++ /* bifurcation; lane1 when using 1+1 */ ++ status = "disabled"; ++ ++ pcie3x1_intc: legacy-interrupt-controller { ++ interrupt-controller; ++ #address-cells = <0>; ++ #interrupt-cells = <1>; ++ interrupt-parent = <&gic>; ++ interrupts = ; ++ }; ++ }; ++ ++ pcie3x2: pcie@fe280000 { ++ compatible = "rockchip,rk3568-pcie"; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ bus-range = <0x0 0xf>; ++ clocks = <&cru ACLK_PCIE30X2_MST>, <&cru ACLK_PCIE30X2_SLV>, ++ <&cru ACLK_PCIE30X2_DBI>, <&cru PCLK_PCIE30X2>, ++ <&cru CLK_PCIE30X2_AUX_NDFT>; ++ clock-names = "aclk_mst", "aclk_slv", ++ "aclk_dbi", "pclk", "aux"; ++ device_type = "pci"; ++ interrupts = , ++ , ++ , ++ , ++ ; ++ interrupt-names = "sys", "pmc", "msg", "legacy", "err"; ++ #interrupt-cells = <1>; ++ interrupt-map-mask = <0 0 0 7>; ++ interrupt-map = <0 0 0 1 &pcie3x2_intc 0>, ++ <0 0 0 2 &pcie3x2_intc 1>, ++ <0 0 0 3 &pcie3x2_intc 2>, ++ <0 0 0 4 &pcie3x2_intc 3>; ++ linux,pci-domain = <2>; ++ num-ib-windows = <6>; ++ num-ob-windows = <2>; ++ max-link-speed = <3>; ++ msi-map = <0x0 &gic 0x2000 0x1000>; ++ num-lanes = <2>; ++ phys = <&pcie30phy>; ++ phy-names = "pcie-phy"; ++ power-domains = <&power RK3568_PD_PIPE>; ++ reg = <0x3 0xc0800000 0x0 0x00400000>, ++ <0x0 0xfe280000 0x0 0x00010000>, ++ <0x3 0xbf000000 0x0 0x01000000>; ++ ranges = <0x01000000 0x0 0x3ef00000 0x3 0xbef00000 0x0 0x00100000>, ++ <0x02000000 0x0 0x00000000 0x3 0x80000000 0x0 0x3ef00000>; ++ reg-names = "dbi", "apb", "config"; ++ resets = <&cru SRST_PCIE30X2_POWERUP>; ++ reset-names = "pipe"; ++ /* bifurcation; lane0 when using 1+1 */ ++ status = "disabled"; ++ ++ pcie3x2_intc: legacy-interrupt-controller { ++ interrupt-controller; ++ #address-cells = <0>; ++ #interrupt-cells = <1>; ++ interrupt-parent = <&gic>; ++ interrupts = ; ++ }; ++ }; ++ + gmac0: ethernet@fe2a0000 { + compatible = "rockchip,rk3568-gmac", "snps,dwmac-4.20a"; + reg = <0x0 0xfe2a0000 0x0 0x10000>; diff --git a/target/linux/rockchip/patches-5.15/202-rockchip-rk3328-Add-support-for-OrangePi-R1-Plus.patch b/target/linux/rockchip/patches-5.15/202-rockchip-rk3328-Add-support-for-OrangePi-R1-Plus.patch deleted file mode 100644 index 3eb923183..000000000 --- a/target/linux/rockchip/patches-5.15/202-rockchip-rk3328-Add-support-for-OrangePi-R1-Plus.patch +++ /dev/null @@ -1,52 +0,0 @@ ---- a/arch/arm64/boot/dts/rockchip/Makefile -+++ b/arch/arm64/boot/dts/rockchip/Makefile -@@ -10,6 +10,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-od - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-a1.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-evb.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2s.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-orangepi-r1-plus.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock64.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock-pi-e.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-roc-cc.dtb ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dts -@@ -0,0 +1,39 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+#include "rk3328-nanopi-r2s.dts" -+ -+/ { -+ model = "Xunlong Orange Pi R1 Plus"; -+ compatible = "xunlong,orangepi-r1-plus", "rockchip,rk3328"; -+}; -+ -+&lan_led { -+ label = "orangepi-r1-plus:green:lan"; -+}; -+ -+&spi0 { -+ max-freq = <48000000>; -+ status = "okay"; -+ -+ flash@0 { -+ compatible = "jedec,spi-nor"; -+ reg = <0>; -+ spi-max-frequency = <10000000>; -+ }; -+}; -+ -+&sys_led { -+ gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>; -+ label = "orangepi-r1-plus:red:sys"; -+}; -+ -+&sys_led_pin { -+ rockchip,pins = <3 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>; -+}; -+ -+&uart1 { -+ status = "okay"; -+}; -+ -+&wan_led { -+ label = "orangepi-r1-plus:green:wan"; -+}; diff --git a/target/linux/rockchip/patches-5.15/204-rockchip-rk3328-Add-support-for-FriendlyARM-NanoPi-R.patch b/target/linux/rockchip/patches-5.15/204-rockchip-rk3328-Add-support-for-FriendlyARM-NanoPi-R.patch deleted file mode 100644 index bdf78bc16..000000000 --- a/target/linux/rockchip/patches-5.15/204-rockchip-rk3328-Add-support-for-FriendlyARM-NanoPi-R.patch +++ /dev/null @@ -1,60 +0,0 @@ ---- a/arch/arm64/boot/dts/rockchip/Makefile -+++ b/arch/arm64/boot/dts/rockchip/Makefile -@@ -10,6 +10,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-od - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-a1.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-doornet1.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-evb.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2c.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2s.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-orangepi-r1-plus.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock64.dtb ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2c.dts -@@ -0,0 +1,47 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Copyright (c) 2021 FriendlyElec Computer Tech. Co., Ltd. -+ * (http://www.friendlyarm.com) -+ * -+ * Copyright (c) 2021 Tianling Shen -+ */ -+ -+/dts-v1/; -+ -+#include "rk3328-nanopi-r2s.dts" -+ -+/ { -+ model = "FriendlyElec NanoPi R2C"; -+ compatible = "friendlyarm,nanopi-r2c", "rockchip,rk3328"; -+}; -+ -+&gmac2io { -+ phy-handle = <&yt8521s>; -+ -+ mdio { -+ /delete-node/ ethernet-phy@1; -+ -+ yt8521s: ethernet-phy@3 { -+ compatible = "ethernet-phy-id0000.011a", -+ "ethernet-phy-ieee802.3-c22"; -+ reg = <3>; -+ pinctrl-0 = <ð_phy_reset_pin>; -+ pinctrl-names = "default"; -+ reset-assert-us = <10000>; -+ reset-deassert-us = <50000>; -+ reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; -+ }; -+ }; -+}; -+ -+&lan_led { -+ label = "nanopi-r2c:green:lan"; -+}; -+ -+&sys_led { -+ label = "nanopi-r2c:red:sys"; -+}; -+ -+&wan_led { -+ label = "nanopi-r2c:green:wan"; -+}; diff --git a/target/linux/rockchip/patches-5.15/206-rockchip-rk3328-Add-support-for-OrangePi-R1-Plus-LTS.patch b/target/linux/rockchip/patches-5.15/206-rockchip-rk3328-Add-support-for-OrangePi-R1-Plus-LTS.patch deleted file mode 100644 index 4b3a3d0d5..000000000 --- a/target/linux/rockchip/patches-5.15/206-rockchip-rk3328-Add-support-for-OrangePi-R1-Plus-LTS.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 9f0bfe430a5a67b34bc2274a898b4375a321810b Mon Sep 17 00:00:00 2001 -From: baiywt -Date: Mon, 15 Nov 2021 16:51:43 +0800 -Subject: [PATCH] Add support for OrangePi R1 Plus LTS - ---- - arch/arm64/boot/dts/rockchip/Makefile | 1 + - .../rockchip/rk3328-orangepi-r1-plus-lts.dts | 44 +++++++++++++++++++ - 2 files changed, 45 insertions(+) - create mode 100644 arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus-lts.dts - ---- a/arch/arm64/boot/dts/rockchip/Makefile -+++ b/arch/arm64/boot/dts/rockchip/Makefile -@@ -13,6 +13,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-ev - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2c.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2s.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-orangepi-r1-plus.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-orangepi-r1-plus-lts.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock64.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock-pi-e.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-roc-cc.dtb ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus-lts.dts -@@ -0,0 +1,70 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+#include "rk3328-orangepi-r1-plus.dts" -+ -+/ { -+ model = "Xunlong Orange Pi R1 Plus LTS"; -+ compatible = "xunlong,orangepi-r1-plus-lts", "rockchip,rk3328"; -+}; -+ -+/delete-node/ &rtl8211e; -+&gmac2io { -+ phy-handle = <ðphy3>; -+ snps,reset-delays-us = <0 15000 50000>; -+ tx_delay = <0x19>; -+ rx_delay = <0x05>; -+ status = "okay"; -+ -+ mdio { -+ compatible = "snps,dwmac-mdio"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ ethphy3: ethernet-phy@0 { -+ reg = <0x0>; -+ keep-clkout-on; -+ reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; -+ }; -+ }; -+}; -+ -+&sdmmc { -+ bus-width = <4>; -+ cap-sd-highspeed; -+ disable-wp; -+ pinctrl-0 = <&sdmmc0_clk>, <&sdmmc0_cmd>, <&sdmmc0_dectn>, <&sdmmc0_bus4>; -+ pinctrl-names = "default"; -+ sd-uhs-sdr12; -+ sd-uhs-sdr25; -+ sd-uhs-sdr50; -+ sd-uhs-sdr104; -+ vmmc-supply = <&vcc_sd>; -+ vqmmc-supply = <&vcc_io_sdio>; -+ status = "okay"; -+}; -+ -+&dmc_opp_table { -+ opp-1056000000 { -+ status = "disabled"; -+ }; -+ opp-924000000 { -+ status = "disabled"; -+ }; -+ opp-840000000 { -+ status = "disabled"; -+ }; -+ opp-798000000 { -+ status = "disabled"; -+ }; -+}; -+ -+&sys_led { -+ label = "orangepi-r1-plus-lts:red:sys"; -+}; -+ -+&wan_led { -+ label = "orangepi-r1-plus-lts:green:wan"; -+}; -+ -+&lan_led { -+ label = "orangepi-r1-plus-lts:green:lan"; -+}; diff --git a/target/linux/rockchip/patches-5.15/207-rockchip-rk3328-add-support-for-FriendlyARM-NanoPi-Neo3.patch b/target/linux/rockchip/patches-5.15/207-rockchip-rk3328-add-support-for-FriendlyARM-NanoPi-Neo3.patch index 7c707d292..40c3f61ce 100644 --- a/target/linux/rockchip/patches-5.15/207-rockchip-rk3328-add-support-for-FriendlyARM-NanoPi-Neo3.patch +++ b/target/linux/rockchip/patches-5.15/207-rockchip-rk3328-add-support-for-FriendlyARM-NanoPi-Neo3.patch @@ -33,20 +33,6 @@ to status_led in accordance with the board schematics. 2 files changed, 397 insertions(+) create mode 100644 arch/arm64/boot/dts/rockchip/rk3328-nanopi-neo3.dts ---- a/arch/arm64/boot/dts/rockchip/Makefile -+++ b/arch/arm64/boot/dts/rockchip/Makefile -@@ -10,6 +10,11 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-od - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-a1.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-doornet1.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-evb.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-neo3.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-nanopi-r4se.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-r66s.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-station-p2.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-nanopi-r5s.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2c.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2s.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-orangepi-r1-plus.dtb --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-neo3.dts @@ -0,0 +1,394 @@ diff --git a/target/linux/rockchip/patches-5.15/802-arm64-dts-rockchip-add-hardware-random-number-genera.patch b/target/linux/rockchip/patches-5.15/802-arm64-dts-rockchip-add-hardware-random-number-genera.patch index 8eea25381..7157acd2a 100644 --- a/target/linux/rockchip/patches-5.15/802-arm64-dts-rockchip-add-hardware-random-number-genera.patch +++ b/target/linux/rockchip/patches-5.15/802-arm64-dts-rockchip-add-hardware-random-number-genera.patch @@ -48,3 +48,22 @@ Signed-off-by: wevsty gpu: gpu@ff9a0000 { compatible = "rockchip,rk3399-mali", "arm,mali-t860"; reg = <0x0 0xff9a0000 0x0 0x10000>; +--- a/arch/arm64/boot/dts/rockchip/rk3568.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3568.dtsi +@@ -211,6 +211,16 @@ + }; + }; + ++ rng: rng@fe388000 { ++ compatible = "rockchip,cryptov2-rng"; ++ reg = <0x0 0xfe388000 0x0 0x2000>; ++ clocks = <&cru CLK_TRNG_NS>, <&cru HCLK_TRNG_NS>; ++ clock-names = "clk_trng", "hclk_trng"; ++ resets = <&cru SRST_TRNG_NS>; ++ reset-names = "reset"; ++ status = "disabled"; ++ }; ++ + combphy0: phy@fe820000 { + compatible = "rockchip,rk3568-naneng-combphy"; + reg = <0x0 0xfe820000 0x0 0x100>; diff --git a/target/linux/rockchip/patches-5.15/900-arm64-boot-add-dts-files.patch b/target/linux/rockchip/patches-5.15/900-arm64-boot-add-dts-files.patch new file mode 100644 index 000000000..0da660510 --- /dev/null +++ b/target/linux/rockchip/patches-5.15/900-arm64-boot-add-dts-files.patch @@ -0,0 +1,24 @@ +--- a/arch/arm64/boot/dts/rockchip/Makefile ++++ b/arch/arm64/boot/dts/rockchip/Makefile +@@ -9,7 +9,12 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3318-a9 + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-odroid-go2.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-a1.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-evb.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2c.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-neo3.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-nanopi-r4se.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2s.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-orangepi-r1-plus.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-orangepi-r1-plus-lts.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock64.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock-pi-e.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-roc-cc.dtb +@@ -51,4 +54,8 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-ro + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-sapphire.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-sapphire-excavator.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399pro-rock-pi-n10.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-rock-3a.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-r66s.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-station-p2.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-nanopi-r5s.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-v10.dtb diff --git a/target/linux/rockchip/patches-5.19/0046-phy-rockchip-Support-PCIe-v3.patch b/target/linux/rockchip/patches-5.19/0046-phy-rockchip-Support-PCIe-v3.patch index d774aaa10..b678f102f 100644 --- a/target/linux/rockchip/patches-5.19/0046-phy-rockchip-Support-PCIe-v3.patch +++ b/target/linux/rockchip/patches-5.19/0046-phy-rockchip-Support-PCIe-v3.patch @@ -53,338 +53,3 @@ Signed-off-by: Frank Wunderlich +obj-$(CONFIG_PHY_ROCKCHIP_SNPS_PCIE3) += phy-rockchip-snps-pcie3.o obj-$(CONFIG_PHY_ROCKCHIP_TYPEC) += phy-rockchip-typec.o obj-$(CONFIG_PHY_ROCKCHIP_USB) += phy-rockchip-usb.o ---- /dev/null -+++ b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c -@@ -0,0 +1,317 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Rockchip PCIE3.0 phy driver -+ * -+ * Copyright (C) 2020 Rockchip Electronics Co., Ltd. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* Register for RK3568 */ -+#define GRF_PCIE30PHY_CON1 0x4 -+#define GRF_PCIE30PHY_CON6 0x18 -+#define GRF_PCIE30PHY_CON9 0x24 -+#define GRF_PCIE30PHY_STATUS0 0x80 -+#define SRAM_INIT_DONE(reg) (reg & BIT(14)) -+ -+#define RK3568_BIFURCATION_LANE_0_1 BIT(0) -+ -+/* Register for RK3588 */ -+#define PHP_GRF_PCIESEL_CON 0x100 -+#define RK3588_PCIE3PHY_GRF_CMN_CON0 0x0 -+#define RK3588_PCIE3PHY_GRF_PHY0_STATUS1 0x904 -+#define RK3588_PCIE3PHY_GRF_PHY1_STATUS1 0xa04 -+#define RK3588_SRAM_INIT_DONE(reg) (reg & BIT(0)) -+ -+#define RK3588_BIFURCATION_LANE_0_1 BIT(0) -+#define RK3588_BIFURCATION_LANE_2_3 BIT(1) -+#define RK3588_LANE_AGGREGATION BIT(2) -+ -+struct rockchip_p3phy_ops; -+ -+struct rockchip_p3phy_priv { -+ const struct rockchip_p3phy_ops *ops; -+ void __iomem *mmio; -+ /* mode: RC, EP */ -+ int mode; -+ /* pcie30_phymode: Aggregation, Bifurcation */ -+ int pcie30_phymode; -+ struct regmap *phy_grf; -+ struct regmap *pipe_grf; -+ struct reset_control *p30phy; -+ struct phy *phy; -+ struct clk_bulk_data *clks; -+ int num_clks; -+ int num_lanes; -+ u32 lanes[4]; -+}; -+ -+struct rockchip_p3phy_ops { -+ int (*phy_init)(struct rockchip_p3phy_priv *priv); -+}; -+ -+static int rockchip_p3phy_set_mode(struct phy *phy, enum phy_mode mode, int submode) -+{ -+ struct rockchip_p3phy_priv *priv = phy_get_drvdata(phy); -+ -+ /* Actually We don't care EP/RC mode, but just record it */ -+ switch (submode) { -+ case PHY_MODE_PCIE_RC: -+ priv->mode = PHY_MODE_PCIE_RC; -+ break; -+ case PHY_MODE_PCIE_EP: -+ priv->mode = PHY_MODE_PCIE_EP; -+ break; -+ default: -+ dev_err(&phy->dev, "%s, invalid mode\n", __func__); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int rockchip_p3phy_rk3568_init(struct rockchip_p3phy_priv *priv) -+{ -+ struct phy *phy = priv->phy; -+ bool bifurcation = false; -+ int ret; -+ u32 reg; -+ -+ /* Deassert PCIe PMA output clamp mode */ -+ regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON9, BIT(15) | BIT(31)); -+ -+ for (int i = 0; i < priv->num_lanes; i++) { -+ dev_info(&phy->dev, "lane number %d, val %d\n", i, priv->lanes[i]); -+ if (priv->lanes[i] > 1) -+ bifurcation = true; -+ } -+ -+ /* Set bifurcation if needed, and it doesn't care RC/EP */ -+ if (bifurcation) { -+ dev_info(&phy->dev, "bifurcation enabled\n"); -+ regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON6, -+ (0xf << 16) | RK3568_BIFURCATION_LANE_0_1); -+ regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON1, -+ BIT(15) | BIT(31)); -+ } else { -+ dev_info(&phy->dev, "bifurcation disabled\n"); -+ regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON6, -+ (0xf << 16) & ~RK3568_BIFURCATION_LANE_0_1); -+ } -+ -+ reset_control_deassert(priv->p30phy); -+ -+ ret = regmap_read_poll_timeout(priv->phy_grf, -+ GRF_PCIE30PHY_STATUS0, -+ reg, SRAM_INIT_DONE(reg), -+ 0, 500); -+ if (ret) -+ dev_err(&priv->phy->dev, "%s: lock failed 0x%x, check input refclk and power supply\n", -+ __func__, reg); -+ return ret; -+} -+ -+static const struct rockchip_p3phy_ops rk3568_ops = { -+ .phy_init = rockchip_p3phy_rk3568_init, -+}; -+ -+static int rockchip_p3phy_rk3588_init(struct rockchip_p3phy_priv *priv) -+{ -+ u32 reg = 0; -+ u8 mode = 0; -+ int ret; -+ -+ /* Deassert PCIe PMA output clamp mode */ -+ regmap_write(priv->phy_grf, RK3588_PCIE3PHY_GRF_CMN_CON0, BIT(8) | BIT(24)); -+ -+ /* Set bifurcation if needed */ -+ for (int i = 0; i < priv->num_lanes; i++) { -+ if (!priv->lanes[i]) -+ mode |= (BIT(i) << 3); -+ -+ if (priv->lanes[i] > 1) -+ mode |= (BIT(i) >> 1); -+ } -+ -+ if (!mode) -+ reg = RK3588_LANE_AGGREGATION; -+ else { -+ if (mode & (BIT(0) | BIT(1))) -+ reg |= RK3588_BIFURCATION_LANE_0_1; -+ -+ if (mode & (BIT(2) | BIT(3))) -+ reg |= RK3588_BIFURCATION_LANE_2_3; -+ } -+ -+ regmap_write(priv->phy_grf, RK3588_PCIE3PHY_GRF_CMN_CON0, (0x7<<16) | reg); -+ -+ /* Set pcie1ln_sel in PHP_GRF_PCIESEL_CON */ -+ if (!IS_ERR(priv->pipe_grf)) { -+ reg = (mode & (BIT(6) | BIT(7))) >> 6; -+ if (reg) -+ regmap_write(priv->pipe_grf, PHP_GRF_PCIESEL_CON, -+ (reg << 16) | reg); -+ } -+ -+ reset_control_deassert(priv->p30phy); -+ -+ ret = regmap_read_poll_timeout(priv->phy_grf, -+ RK3588_PCIE3PHY_GRF_PHY0_STATUS1, -+ reg, RK3588_SRAM_INIT_DONE(reg), -+ 0, 500); -+ ret |= regmap_read_poll_timeout(priv->phy_grf, -+ RK3588_PCIE3PHY_GRF_PHY1_STATUS1, -+ reg, RK3588_SRAM_INIT_DONE(reg), -+ 0, 500); -+ if (ret) -+ pr_err("%s: lock failed 0x%x, check input refclk and power supply\n", -+ __func__, reg); -+ return ret; -+} -+ -+static const struct rockchip_p3phy_ops rk3588_ops = { -+ .phy_init = rockchip_p3phy_rk3588_init, -+}; -+ -+static int rochchip_p3phy_init(struct phy *phy) -+{ -+ struct rockchip_p3phy_priv *priv = phy_get_drvdata(phy); -+ int ret; -+ -+ ret = clk_bulk_prepare_enable(priv->num_clks, priv->clks); -+ if (ret) { -+ pr_err("failed to enable PCIe bulk clks %d\n", ret); -+ return ret; -+ } -+ -+ reset_control_assert(priv->p30phy); -+ udelay(1); -+ -+ if (priv->ops->phy_init) { -+ ret = priv->ops->phy_init(priv); -+ if (ret) -+ clk_bulk_disable_unprepare(priv->num_clks, priv->clks); -+ } -+ -+ return ret; -+} -+ -+static int rochchip_p3phy_exit(struct phy *phy) -+{ -+ struct rockchip_p3phy_priv *priv = phy_get_drvdata(phy); -+ -+ clk_bulk_disable_unprepare(priv->num_clks, priv->clks); -+ reset_control_assert(priv->p30phy); -+ return 0; -+} -+ -+static const struct phy_ops rochchip_p3phy_ops = { -+ .init = rochchip_p3phy_init, -+ .exit = rochchip_p3phy_exit, -+ .set_mode = rockchip_p3phy_set_mode, -+ .owner = THIS_MODULE, -+}; -+ -+static int rockchip_p3phy_probe(struct platform_device *pdev) -+{ -+ struct phy_provider *phy_provider; -+ struct device *dev = &pdev->dev; -+ struct rockchip_p3phy_priv *priv; -+ struct device_node *np = dev->of_node; -+ struct resource *res; -+ int ret; -+ -+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ priv->mmio = devm_ioremap_resource(dev, res); -+ if (IS_ERR(priv->mmio)) { -+ ret = PTR_ERR(priv->mmio); -+ return ret; -+ } -+ -+ priv->ops = of_device_get_match_data(&pdev->dev); -+ if (!priv->ops) { -+ dev_err(&pdev->dev, "no of match data provided\n"); -+ return -EINVAL; -+ } -+ -+ priv->phy_grf = syscon_regmap_lookup_by_phandle(np, "rockchip,phy-grf"); -+ if (IS_ERR(priv->phy_grf)) { -+ dev_err(dev, "failed to find rockchip,phy_grf regmap\n"); -+ return PTR_ERR(priv->phy_grf); -+ } -+ -+ priv->pipe_grf = syscon_regmap_lookup_by_phandle(dev->of_node, -+ "rockchip,pipe-grf"); -+ if (IS_ERR(priv->pipe_grf)) -+ dev_info(dev, "failed to find rockchip,pipe_grf regmap\n"); -+ -+ priv->num_lanes = of_property_read_variable_u32_array(dev->of_node, "data-lanes", -+ priv->lanes, 2, -+ ARRAY_SIZE(priv->lanes)); -+ -+ /* if no data-lanes assume aggregation */ -+ if (priv->num_lanes == -EINVAL) { -+ dev_dbg(dev, "no data-lanes property found\n"); -+ priv->num_lanes = 1; -+ priv->lanes[0] = 1; -+ } else if (priv->num_lanes < 0) { -+ dev_err(dev, "failed to read data-lanes property %d\n", priv->num_lanes); -+ return priv->num_lanes; -+ } -+ -+ priv->phy = devm_phy_create(dev, NULL, &rochchip_p3phy_ops); -+ if (IS_ERR(priv->phy)) { -+ dev_err(dev, "failed to create combphy\n"); -+ return PTR_ERR(priv->phy); -+ } -+ -+ priv->p30phy = devm_reset_control_get_optional_exclusive(dev, "phy"); -+ if (IS_ERR(priv->p30phy)) { -+ return dev_err_probe(dev, PTR_ERR(priv->p30phy), -+ "failed to get phy reset control\n"); -+ } -+ if (!priv->p30phy) -+ dev_info(dev, "no phy reset control specified\n"); -+ -+ priv->num_clks = devm_clk_bulk_get_all(dev, &priv->clks); -+ if (priv->num_clks < 1) -+ return -ENODEV; -+ -+ dev_set_drvdata(dev, priv); -+ phy_set_drvdata(priv->phy, priv); -+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); -+ return PTR_ERR_OR_ZERO(phy_provider); -+} -+ -+static const struct of_device_id rockchip_p3phy_of_match[] = { -+ { .compatible = "rockchip,rk3568-pcie3-phy", .data = &rk3568_ops }, -+ { .compatible = "rockchip,rk3588-pcie3-phy", .data = &rk3588_ops }, -+ { }, -+}; -+MODULE_DEVICE_TABLE(of, rockchip_p3phy_of_match); -+ -+static struct platform_driver rockchip_p3phy_driver = { -+ .probe = rockchip_p3phy_probe, -+ .driver = { -+ .name = "rockchip-snps-pcie3-phy", -+ .of_match_table = rockchip_p3phy_of_match, -+ }, -+}; -+module_platform_driver(rockchip_p3phy_driver); -+MODULE_DESCRIPTION("Rockchip Synopsys PCIe 3.0 PHY driver"); -+MODULE_LICENSE("GPL"); ---- /dev/null -+++ b/include/linux/phy/pcie.h -@@ -0,0 +1,12 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (c) 2021 Rockchip Electronics Co., Ltd. -+ */ -+#ifndef __PHY_PCIE_H -+#define __PHY_PCIE_H -+ -+#define PHY_MODE_PCIE_RC 20 -+#define PHY_MODE_PCIE_EP 21 -+#define PHY_MODE_PCIE_BIFURCATION 22 -+ -+#endif diff --git a/target/linux/rockchip/patches-5.19/0800-rockchip-snps-pcie3-update-fw-when-init.patch b/target/linux/rockchip/patches-5.19/0800-rockchip-snps-pcie3-update-fw-when-init.patch deleted file mode 100644 index bfc2d73ab..000000000 --- a/target/linux/rockchip/patches-5.19/0800-rockchip-snps-pcie3-update-fw-when-init.patch +++ /dev/null @@ -1,8274 +0,0 @@ -From c056c33a88c05d64bfac3687e6fbab978c7d1f57 Mon Sep 17 00:00:00 2001 -From: Kever Yang -Date: Fri, 13 May 2022 09:54:12 +0800 -Subject: [PATCH] phy: rockchip-snps-pcie3: update fw when init - -Signed-off-by: Kever Yang -Signed-off-by: jensen ---- - drivers/phy/rockchip/p3phy.fw | 8192 +++++++++++++++++ - .../phy/rockchip/phy-rockchip-snps-pcie3.c | 37 +- - 2 files changed, 8220 insertions(+), 9 deletions(-) - create mode 100644 drivers/phy/rockchip/p3phy.fw - ---- /dev/null -+++ b/drivers/phy/rockchip/p3phy.fw -@@ -0,0 +1,8192 @@ -+0x081D, -+0xFFFF, -+0x33AF, -+0x33AE, -+0x0C4F, -+0xD10D, -+0x0D0F, -+0xD306, -+0x0C8F, -+0xDB06, -+0x33AF, -+0xD38D, -+0x01AC, -+0x2000, -+0x0C1E, -+0x014A, -+0x2800, -+0x1B80, -+0xA0B2, -+0x0806, -+0x0016, -+0x8CC7, -+0xD1AE, -+0x0C2E, -+0x1B75, -+0x33AE, -+0xA01C, -+0x8026, -+0x0C2F, -+0xD375, -+0x33AF, -+0x1B81, -+0xA022, -+0x8026, -+0x0D8F, -+0x03A6, -+0x0003, -+0x33AF, -+0x0C6F, -+0xDBA6, -+0x33AF, -+0x0C4F, -+0xD10D, -+0x33AF, -+0x0D8F, -+0xDBA6, -+0x33AF, -+0x1B81, -+0xA032, -+0x8048, -+0xDB87, -+0x038D, -+0x0020, -+0xD310, -+0x080F, -+0x0020, -+0xD106, -+0x33AF, -+0xDB8B, -+0xDB8C, -+0x1B0F, -+0xA03A, -+0x0807, -+0x0044, -+0x33FE, -+0x0C01, -+0x0C3F, -+0x80BA, -+0x0C4F, -+0xD30E, -+0x33AF, -+0xD38D, -+0x1B82, -+0xA04B, -+0x8061, -+0xDB88, -+0x080F, -+0x0020, -+0xD106, -+0x33AF, -+0x1B8E, -+0xA053, -+0x8061, -+0x1BA7, -+0xA056, -+0x8053, -+0x0807, -+0x005C, -+0x33FE, -+0x0C01, -+0x0C3F, -+0x80BA, -+0xDB8F, -+0x0C2E, -+0x1B09, -+0xA05D, -+0x33AE, -+0x1B86, -+0xA07B, -+0x1B85, -+0xA0A7, -+0x080E, -+0x0200, -+0x1BF6, -+0x33AE, -+0xA074, -+0x1B5E, -+0xA06D, -+0x8077, -+0x0C4E, -+0x1BF6, -+0x33AE, -+0xA077, -+0x0806, -+0x0000, -+0x89A4, -+0x0C4F, -+0xDBF6, -+0x33AF, -+0x1B2F, -+0xA07A, -+0x89DF, -+0x8000, -+0x080F, -+0x0020, -+0xD106, -+0x33AF, -+0x0807, -+0x0085, -+0x33FE, -+0x0C01, -+0x0C3F, -+0x80BA, -+0xD35E, -+0x038D, -+0x0020, -+0xD10D, -+0x010D, -+0x0002, -+0x0C8F, -+0xDB06, -+0x33AF, -+0x0D0F, -+0xDB06, -+0x33AF, -+0x0C2E, -+0x1919, -+0xA095, -+0x8092, -+0x33AE, -+0x0C8F, -+0xD306, -+0x33AF, -+0x0C2E, -+0x1919, -+0xA09D, -+0x33AE, -+0x0D0F, -+0xD306, -+0x33AF, -+0xD10D, -+0xD38D, -+0xDB10, -+0xDB8C, -+0xDB8B, -+0xD310, -+0x8000, -+0xDB8B, -+0xD35E, -+0x0806, -+0x0000, -+0x1B28, -+0xA995, -+0x0806, -+0x0000, -+0x038D, -+0x0020, -+0x86F1, -+0xD380, -+0x1B59, -+0xA19E, -+0x80C8, -+0x0C4F, -+0xD3F6, -+0x33AF, -+0x080E, -+0x01FC, -+0x1BF6, -+0x33AE, -+0xA0C3, -+0x080F, -+0x01FC, -+0x03F6, -+0x0032, -+0x33AF, -+0x0806, -+0x0157, -+0x1B27, -+0xA641, -+0x822B, -+0x0367, -+0x003F, -+0x0368, -+0x0C09, -+0x0369, -+0x7928, -+0xD36A, -+0x036B, -+0x007F, -+0x036C, -+0x0C13, -+0x036D, -+0x7803, -+0xD36E, -+0x037C, -+0x003F, -+0x037D, -+0x0C01, -+0x037E, -+0x7818, -+0xD37F, -+0x03E0, -+0x007F, -+0x03E1, -+0x0C2F, -+0x03E2, -+0x7828, -+0x03E3, -+0x36DC, -+0x03E4, -+0x007F, -+0x03E5, -+0x0C09, -+0x03E6, -+0x7818, -+0x03E7, -+0x124A, -+0x080E, -+0xFF00, -+0x191E, -+0x33AE, -+0x080F, -+0x00FF, -+0x291D, -+0x0CCF, -+0xD11D, -+0x080F, -+0x0100, -+0xD91D, -+0x33AF, -+0x0C2F, -+0xD375, -+0x33AF, -+0x0349, -+0x0017, -+0x0353, -+0x0017, -+0x1B4A, -+0x29B4, -+0xD9B8, -+0x0229, -+0x1060, -+0x022A, -+0x0E24, -+0x080E, -+0x4000, -+0x1B09, -+0xA108, -+0x0C2E, -+0x1B02, -+0xA10C, -+0x33AE, -+0xD317, -+0x1B29, -+0xA115, -+0x705E, -+0x8115, -+0x1B2D, -+0xA118, -+0x811A, -+0x014B, -+0x2DAB, -+0x1B2E, -+0xA11D, -+0x811F, -+0x014C, -+0x004B, -+0x1B2A, -+0xA123, -+0x0125, -+0x065A, -+0x1B2B, -+0xA126, -+0x8128, -+0x0127, -+0x0D07, -+0x0063, -+0x7F00, -+0x0073, -+0x7F00, -+0x1A28, -+0xA145, -+0xDA28, -+0x1B29, -+0xA137, -+0x0060, -+0x0008, -+0x0070, -+0x0008, -+0xDBA8, -+0x8140, -+0x0C2F, -+0xD881, -+0x080F, -+0xFFFF, -+0xDBA8, -+0x0061, -+0x0018, -+0x0071, -+0x0018, -+0x0301, -+0x0F05, -+0x03A0, -+0x0007, -+0x8147, -+0x0301, -+0x0F05, -+0x1B2C, -+0xA14C, -+0x0144, -+0x0100, -+0x8152, -+0x080F, -+0x0200, -+0xD944, -+0x33AF, -+0x0145, -+0x6DB4, -+0x0306, -+0x0006, -+0x1B0F, -+0xA154, -+0x80B6, -+0x0305, -+0x000C, -+0x0306, -+0x0007, -+0x0317, -+0x0003, -+0x0306, -+0x0006, -+0x1B0F, -+0xA15F, -+0x0306, -+0x0004, -+0xDB87, -+0x1A28, -+0x5C6D, -+0xA168, -+0x816E, -+0x13A3, -+0x5CEC, -+0xA168, -+0x0228, -+0x0003, -+0x816E, -+0x0C2E, -+0x1A11, -+0x33AE, -+0xA177, -+0x1867, -+0x080C, -+0x0100, -+0x518D, -+0x2B54, -+0x0C4E, -+0x1A11, -+0x33AE, -+0xA180, -+0x1877, -+0x080C, -+0x0100, -+0x518D, -+0x2B55, -+0x1867, -+0x2868, -+0x1877, -+0x2878, -+0x1886, -+0x2B56, -+0x1888, -+0x2B58, -+0x1887, -+0x2B57, -+0x0060, -+0x0018, -+0x0070, -+0x0018, -+0xDA12, -+0xD3A0, -+0xD3A8, -+0xDB59, -+0x7005, -+0x0C4F, -+0xD081, -+0x080F, -+0xFFFF, -+0x0C8F, -+0xD303, -+0x33AF, -+0x0C4F, -+0xD30E, -+0x33AF, -+0x8000, -+0x1B54, -+0x2868, -+0x1B55, -+0x2878, -+0x705E, -+0x1B2D, -+0xA1A6, -+0x81A8, -+0x014B, -+0x2DAB, -+0x1B2E, -+0xA1AB, -+0x81AD, -+0x014C, -+0x004B, -+0x1B29, -+0xA1B0, -+0x81B8, -+0x0C2F, -+0xD881, -+0x080F, -+0xFFFF, -+0x0061, -+0x0018, -+0x0071, -+0x0018, -+0x1B56, -+0x2883, -+0x1B58, -+0x2885, -+0x1B57, -+0x2884, -+0x0301, -+0x0F05, -+0xD9AE, -+0x01AD, -+0x0080, -+0xD1AF, -+0xD9B6, -+0x1B40, -+0x29AD, -+0xD9AF, -+0xD9B6, -+0x1B41, -+0x29AD, -+0x01AF, -+0x0002, -+0xD9B6, -+0x1B42, -+0x29AD, -+0x01AF, -+0x0003, -+0xD9B6, -+0x1B45, -+0x29AD, -+0x01AF, -+0x0014, -+0xD9B6, -+0x1B46, -+0x29AD, -+0x01AF, -+0x0015, -+0xD9B6, -+0x01A8, -+0x0140, -+0x1B4B, -+0x2973, -+0x1B4C, -+0x2974, -+0x1B51, -+0x2979, -+0x1B4D, -+0x2975, -+0x1B4E, -+0x2976, -+0x1B52, -+0x297A, -+0x1BF2, -+0x5C6D, -+0xA1F1, -+0x0C4F, -+0xD9BA, -+0x33AF, -+0x0C8E, -+0x1B24, -+0x33AE, -+0xA1F6, -+0x81F9, -+0x0C2F, -+0xD9BA, -+0x33AF, -+0x1B4F, -+0x080F, -+0xFF00, -+0x297F, -+0x080F, -+0xFFFF, -+0x1B50, -+0x080F, -+0x00FF, -+0x297F, -+0x080F, -+0xFFFF, -+0x1B4A, -+0x29B4, -+0xD9B8, -+0xD1AE, -+0xD1A8, -+0x018E, -+0x0019, -+0x0305, -+0x000C, -+0xD306, -+0x1B0F, -+0xA20F, -+0x1B2C, -+0xA214, -+0x821A, -+0x080F, -+0x0200, -+0xD944, -+0x33AF, -+0x0145, -+0x6DB4, -+0x1B04, -+0xA21A, -+0x1B2A, -+0xA220, -+0x0125, -+0x065A, -+0x1B2B, -+0xA223, -+0x8225, -+0x0127, -+0x0D07, -+0xDA12, -+0x0229, -+0x1060, -+0x022A, -+0xE24 , -+0x8193, -+0x01A8, -+0x0140, -+0x0100, -+0x0004, -+0x018E, -+0x0019, -+0xD9AE, -+0xD9B6, -+0x01B0, -+0x0B37, -+0x01B1, -+0x00FA, -+0xD9B7, -+0x0180, -+0x03FF, -+0xD981, -+0xD182, -+0xD183, -+0x0184, -+0x4000, -+0x0185, -+0x2408, -+0x1B31, -+0xA254, -+0x01A8, -+0x0140, -+0xD1B5, -+0x01AC, -+0xA060, -+0xD9AF, -+0x0340, -+0x0080, -+0x0800, -+0x0340, -+0x01AD, -+0x0080, -+0xD9B6, -+0x0807, -+0x0254, -+0x0C03, -+0x864B, -+0x1B31, -+0xA268, -+0x01A8, -+0x0140, -+0xD1B5, -+0x01AC, -+0xA080, -+0x01AF, -+0x0002, -+0x0341, -+0x0080, -+0x0800, -+0x0341, -+0x01AD, -+0x0080, -+0xD9B6, -+0x0807, -+0x0268, -+0x0C03, -+0x864B, -+0x01B1, -+0x0062, -+0xD9B7, -+0x1B31, -+0xA27E, -+0x01A8, -+0x0140, -+0xD1B5, -+0x01AC, -+0xA080, -+0xD9AF, -+0x0340, -+0x0080, -+0x0800, -+0x0340, -+0x01AD, -+0x0080, -+0xD9B6, -+0x0807, -+0x027E, -+0x0C03, -+0x864B, -+0x1B31, -+0xA292, -+0x01A8, -+0x0140, -+0xD1B5, -+0x01AC, -+0xA0C0, -+0x01AF, -+0x0003, -+0x0342, -+0x0080, -+0x0800, -+0x0342, -+0x01AD, -+0x0080, -+0xD9B6, -+0x0807, -+0x0292, -+0x0C03, -+0x864B, -+0x080E, -+0xF800, -+0x1B0C, -+0x31A1, -+0x080E, -+0x07FF, -+0x1B0C, -+0x31A2, -+0xD11D, -+0x0CEE, -+0x1B0D, -+0x31A3, -+0x33AE, -+0x304D, -+0x080F, -+0x07FF, -+0x29B0, -+0x33AF, -+0x302D, -+0x080F, -+0x00F8, -+0x29B1, -+0x33AF, -+0x306D, -+0x0CEF, -+0x29B1, -+0x33AF, -+0xD9B7, -+0x0C2E, -+0x1BF6, -+0x33AE, -+0xA2CD, -+0x0180, -+0x03FF, -+0xD981, -+0xD182, -+0xD183, -+0x0184, -+0x4000, -+0x0185, -+0x2408, -+0x01A8, -+0x0140, -+0xD1B5, -+0x01AC, -+0xB080, -+0x01AF, -+0x0002, -+0x03F7, -+0x0080, -+0x0800, -+0x03F7, -+0x01AD, -+0x0080, -+0xD9B6, -+0x0807, -+0x02CD, -+0x0C03, -+0x864B, -+0x0C8E, -+0x1BF4, -+0x33AE, -+0xA2EC, -+0x0180, -+0x03FF, -+0xD981, -+0xD182, -+0xD183, -+0x0184, -+0x4000, -+0x0185, -+0x2408, -+0x01A8, -+0x0140, -+0xD1B5, -+0x01AC, -+0xB0C0, -+0x01AF, -+0x0003, -+0x03EC, -+0x0080, -+0x0800, -+0x03EC, -+0x01AD, -+0x0080, -+0xD9B6, -+0x0807, -+0x02EC, -+0x0C03, -+0x864B, -+0x01B3, -+0x0177, -+0xD3F2, -+0x0C2E, -+0x1BF4, -+0x33AE, -+0xA313, -+0x0180, -+0x01FF, -+0x0181, -+0xAAAA, -+0x0182, -+0x2800, -+0xD183, -+0x0184, -+0x6C00, -+0x0185, -+0x2408, -+0x0807, -+0x0301, -+0x8DC7, -+0x01A8, -+0x0140, -+0xD1B5, -+0x01AC, -+0x3000, -+0x01AF, -+0x0016, -+0x0179, -+0x0080, -+0x0800, -+0x0179, -+0x01AD, -+0x0080, -+0xD9B6, -+0x0807, -+0x0313, -+0x0C23, -+0x864B, -+0x0800, -+0x0179, -+0x3801, -+0x0802, -+0x003F, -+0x0803, -+0x00C0, -+0x5461, -+0xB31F, -+0x5422, -+0xB31F, -+0x8329, -+0x0C4E, -+0x19BA, -+0x33AE, -+0xA329, -+0x1B33, -+0xA329, -+0x0C4F, -+0xD9BA, -+0x33AF, -+0x82EF, -+0x0C2E, -+0x1BF4, -+0x33AE, -+0xA34D, -+0x0180, -+0x01FF, -+0x0181, -+0x5555, -+0x0182, -+0x1400, -+0xD183, -+0x0184, -+0x6C00, -+0x0185, -+0x2408, -+0x0807, -+0x033B, -+0x8E5B, -+0x01A8, -+0x0140, -+0xD1B5, -+0x01AC, -+0x3000, -+0x01AF, -+0x0018, -+0x017A, -+0x0080, -+0x0800, -+0x017A, -+0x01AD, -+0x0080, -+0xD9B6, -+0x0807, -+0x034D, -+0x0C23, -+0x864B, -+0x0800, -+0x017A, -+0x3801, -+0x0802, -+0x003F, -+0x0803, -+0x00C0, -+0x5461, -+0xB359, -+0x5422, -+0xB359, -+0x8363, -+0x0C4E, -+0x19BA, -+0x33AE, -+0xA363, -+0x1B33, -+0xA363, -+0x0C4F, -+0xD9BA, -+0x33AF, -+0x82EF, -+0x080E, -+0x0400, -+0x1B6F, -+0x33AE, -+0xA38D, -+0x0C4E, -+0x19BA, -+0x33AE, -+0xA38B, -+0x0800, -+0x009B, -+0x1979, -+0x31A1, -+0x197A, -+0x31A2, -+0x5420, -+0xB375, -+0x8379, -+0x5440, -+0xB379, -+0xDBF2, -+0x838D, -+0x5420, -+0xB381, -+0x5440, -+0xB37E, -+0x8381, -+0x03F2, -+0x0002, -+0x838D, -+0x5420, -+0xB38D, -+0x5440, -+0xB38D, -+0x03F2, -+0x0003, -+0x0C4F, -+0xD9BA, -+0x33AF, -+0x82EF, -+0x03F2, -+0x0003, -+0x1BF2, -+0x5C6D, -+0xA395, -+0x03ED, -+0x0025, -+0x03EE, -+0x0025, -+0x8399, -+0x03ED, -+0x0037, -+0x03EE, -+0x0037, -+0x1B32, -+0xA3BB, -+0x0180, -+0x01FF, -+0x0181, -+0xAAAA, -+0x0182, -+0x2800, -+0xD183, -+0x0184, -+0x7000, -+0x0185, -+0x2408, -+0x0807, -+0x03A9, -+0x8D7D, -+0x01A8, -+0x0140, -+0xD1B5, -+0x01AC, -+0x3000, -+0x01AF, -+0x0010, -+0x0173, -+0x0080, -+0x0800, -+0x0173, -+0x01AD, -+0x0080, -+0xD9B6, -+0x0807, -+0x03BB, -+0x0C23, -+0x864B, -+0x0800, -+0x0173, -+0x3801, -+0x0802, -+0x003F, -+0x0803, -+0x00C0, -+0x5423, -+0xB3C5, -+0x83C7, -+0x5441, -+0xB3D1, -+0x0C4E, -+0x19BA, -+0x33AE, -+0xA3D1, -+0x1B33, -+0xA3D1, -+0x0C4F, -+0xD9BA, -+0x33AF, -+0x82EF, -+0x1B32, -+0xA3F3, -+0x0180, -+0x01FF, -+0x0181, -+0xAAAA, -+0x0182, -+0x2800, -+0xD183, -+0x0184, -+0x7000, -+0x0185, -+0x2408, -+0x0807, -+0x03E1, -+0x8DA1, -+0x01A8, -+0x0140, -+0xD1B5, -+0x01AC, -+0x3000, -+0x01AF, -+0x0011, -+0x0174, -+0x0080, -+0x0800, -+0x0174, -+0x01AD, -+0x0080, -+0xD9B6, -+0x0807, -+0x03F3, -+0x0C23, -+0x864B, -+0x0800, -+0x0174, -+0x3801, -+0x0802, -+0x003F, -+0x0803, -+0x00C0, -+0x5423, -+0xB3FD, -+0x83FF, -+0x5441, -+0xB409, -+0x0C4E, -+0x19BA, -+0x33AE, -+0xA409, -+0x1B33, -+0xA409, -+0x0C4F, -+0xD9BA, -+0x33AF, -+0x82EF, -+0x1B32, -+0xA42B, -+0x0180, -+0x01FF, -+0x0181, -+0x5555, -+0x0182, -+0x1400, -+0xD183, -+0x0184, -+0x7000, -+0x0185, -+0x2408, -+0x0807, -+0x0419, -+0x8E11, -+0x01A8, -+0x0140, -+0xD1B5, -+0x01AC, -+0x3000, -+0x01AF, -+0x0012, -+0x0175, -+0x0080, -+0x0800, -+0x0175, -+0x01AD, -+0x0080, -+0xD9B6, -+0x0807, -+0x042B, -+0x0C23, -+0x864B, -+0x0800, -+0x0175, -+0x3801, -+0x0802, -+0x003F, -+0x0803, -+0x00C0, -+0x5423, -+0xB435, -+0x8437, -+0x5441, -+0xB441, -+0x0C4E, -+0x19BA, -+0x33AE, -+0xA441, -+0x1B33, -+0xA441, -+0x0C4F, -+0xD9BA, -+0x33AF, -+0x82EF, -+0x1B32, -+0xA463, -+0x0180, -+0x01FF, -+0x0181, -+0x5555, -+0x0182, -+0x1400, -+0xD183, -+0x0184, -+0x7000, -+0x0185, -+0x2408, -+0x0807, -+0x0451, -+0x8E35, -+0x01A8, -+0x0140, -+0xD1B5, -+0x01AC, -+0x3000, -+0x01AF, -+0x0013, -+0x0176, -+0x0080, -+0x0800, -+0x0176, -+0x01AD, -+0x0080, -+0xD9B6, -+0x0807, -+0x0463, -+0x0C23, -+0x864B, -+0x0800, -+0x0176, -+0x3801, -+0x0802, -+0x003F, -+0x0803, -+0x00C0, -+0x5423, -+0xB46D, -+0x846F, -+0x5441, -+0xB479, -+0x0C4E, -+0x19BA, -+0x33AE, -+0xA479, -+0x1B33, -+0xA479, -+0x0C4F, -+0xD9BA, -+0x33AF, -+0x82EF, -+0x0C8F, -+0xD324, -+0x33AF, -+0x1B3D, -+0xA49E, -+0x0180, -+0x01FF, -+0x0181, -+0xAAAA, -+0x0182, -+0x2800, -+0xD183, -+0x0184, -+0x6800, -+0x0185, -+0x2408, -+0x0807, -+0x048C, -+0x8DEC, -+0x01A8, -+0x0140, -+0xD1B5, -+0x01AC, -+0x3000, -+0x01AF, -+0x0014, -+0x0345, -+0x0080, -+0x0800, -+0x0345, -+0x01AD, -+0x0080, -+0xD9B6, -+0x0807, -+0x049E, -+0x0C23, -+0x864B, -+0x1B3D, -+0xA4C0, -+0x0180, -+0x01FF, -+0x0181, -+0x5555, -+0x0182, -+0x1400, -+0xD183, -+0x0184, -+0x6800, -+0x0185, -+0x2408, -+0x0807, -+0x04AE, -+0x8E80, -+0x01A8, -+0x0140, -+0xD1B5, -+0x01AC, -+0x3000, -+0x01AF, -+0x0015, -+0x0346, -+0x0080, -+0x0800, -+0x0346, -+0x01AD, -+0x0080, -+0xD9B6, -+0x0807, -+0x04C0, -+0x0C23, -+0x864B, -+0x1B3E, -+0xA4DD, -+0x0800, -+0x00FB, -+0x1B45, -+0x31A1, -+0x1B46, -+0x31A2, -+0x5401, -+0xB4D2, -+0x5402, -+0xB4D2, -+0x0C80, -+0x5420, -+0xB4D2, -+0x5440, -+0xB4D2, -+0x84DD, -+0x0C2E, -+0x19BA, -+0x33AE, -+0xA4DD, -+0x0C8F, -+0xDB24, -+0x33AF, -+0x0C2F, -+0xD9BA, -+0x33AF, -+0x847C, -+0x0C4E, -+0x1BF4, -+0x33AE, -+0xA508, -+0x0180, -+0x01FF, -+0x0181, -+0xAAAA, -+0x0182, -+0x2800, -+0xD183, -+0x0184, -+0x7000, -+0x0185, -+0x2408, -+0x01A8, -+0x0140, -+0xD1B5, -+0x01AC, -+0x3000, -+0x01AF, -+0x0010, -+0x0807, -+0x04F6, -+0x8EA5, -+0x01A8, -+0x0100, -+0xD1B5, -+0x01AC, -+0x3000, -+0x01AF, -+0x0010, -+0x034F, -+0x0080, -+0x0800, -+0x034F, -+0x01AD, -+0x0080, -+0xD9B6, -+0x0807, -+0x0508, -+0x0C23, -+0x864B, -+0x1B4F, -+0x080F, -+0xFF00, -+0x297F, -+0x080F, -+0xFFFF, -+0x0C4E, -+0x1BF4, -+0x33AE, -+0xA539, -+0x0180, -+0x01FF, -+0x0181, -+0x5555, -+0x0182, -+0x1400, -+0xD183, -+0x0184, -+0x7000, -+0x0185, -+0x2408, -+0x01A8, -+0x0140, -+0xD1B5, -+0x01AC, -+0x3000, -+0x01AF, -+0x0012, -+0x0807, -+0x0527, -+0x8EC9, -+0x01A8, -+0x0100, -+0xD1B5, -+0x01AC, -+0x3000, -+0x01AF, -+0x0012, -+0x0350, -+0x0080, -+0x0800, -+0x0350, -+0x01AD, -+0x0080, -+0xD9B6, -+0x0807, -+0x0539, -+0x0C23, -+0x864B, -+0x1B50, -+0x080F, -+0x00FF, -+0x297F, -+0x080F, -+0xFFFF, -+0x0C2E, -+0x1B6F, -+0x33AE, -+0xA5CF, -+0x0CEE, -+0x1B0C, -+0x33AE, -+0x0800, -+0x0080, -+0x51A0, -+0x080F, -+0x07FF, -+0x29B0, -+0x33AF, -+0xD9B7, -+0x0800, -+0x0080, -+0x1BED, -+0x51A0, -+0x2969, -+0x31A0, -+0x01AF, -+0x0016, -+0x21AD, -+0xD9B6, -+0x0180, -+0x03FF, -+0xD981, -+0xD182, -+0xD183, -+0x0184, -+0x4000, -+0x0185, -+0x2408, -+0x01A8, -+0x0100, -+0xD1B5, -+0x01AC, -+0x9346, -+0x01AF, -+0x001B, -+0x03FC, -+0x0080, -+0x0800, -+0x03FC, -+0x01AD, -+0x0080, -+0xD9B6, -+0x0807, -+0x0573, -+0x0C23, -+0x864B, -+0x01A8, -+0x0100, -+0xD1B5, -+0x01AC, -+0x90DA, -+0x01AF, -+0x0003, -+0x03FD, -+0x0080, -+0x0800, -+0x03FD, -+0x01AD, -+0x0080, -+0xD9B6, -+0x0807, -+0x0585, -+0x0C03, -+0x864B, -+0x0180, -+0x01FF, -+0x0181, -+0xAAAA, -+0x0182, -+0x2800, -+0xD183, -+0x0184, -+0x6C00, -+0x0185, -+0x2408, -+0x0807, -+0x0593, -+0x8DC7, -+0x01A8, -+0x0140, -+0xD1B5, -+0x01AC, -+0x3000, -+0x01AF, -+0x0016, -+0x03ED, -+0x0080, -+0x0800, -+0x03ED, -+0x01AD, -+0x0080, -+0xD9B6, -+0x0807, -+0x05A5, -+0x0C23, -+0x864B, -+0x0180, -+0x01FF, -+0x0181, -+0x5555, -+0x0182, -+0x1400, -+0xD183, -+0x0184, -+0x6C00, -+0x0185, -+0x2408, -+0x0807, -+0x05B3, -+0x8E5B, -+0x01A8, -+0x0140, -+0xD1B5, -+0x01AC, -+0x3000, -+0x01AF, -+0x0018, -+0x03EE, -+0x0080, -+0x0800, -+0x03EE, -+0x01AD, -+0x0080, -+0xD9B6, -+0x0807, -+0x05C5, -+0x0C23, -+0x864B, -+0x1BEE, -+0x31A0, -+0x1BED, -+0x31A1, -+0x197A, -+0x55A0, -+0x2BEE, -+0x1979, -+0x55A1, -+0x2BED, -+0x080E, -+0x07F8, -+0x1B0C, -+0x33AE, -+0x080F, -+0x07F8, -+0x29B0, -+0x33AF, -+0xD9B7, -+0x080F, -+0x0800, -+0xD1B0, -+0x33AF, -+0xD9B7, -+0x01A8, -+0x0140, -+0x1973, -+0x29AD, -+0x01AF, -+0x0010, -+0xD9B6, -+0x1974, -+0x29AD, -+0x01AF, -+0x0011, -+0xD9B6, -+0x1979, -+0x29AD, -+0x01AF, -+0x0016, -+0xD9B6, -+0x1B45, -+0x29AD, -+0x01AF, -+0x0014, -+0xD9B6, -+0x1975, -+0x29AD, -+0x01AF, -+0x0012, -+0xD9B6, -+0x1976, -+0x29AD, -+0x01AF, -+0x0013, -+0xD9B6, -+0x197A, -+0x29AD, -+0x01AF, -+0x0018, -+0xD9B6, -+0x1B46, -+0x29AD, -+0x01AF, -+0x0015, -+0xD9B6, -+0x1973, -+0x2B4B, -+0x1974, -+0x2B4C, -+0x1979, -+0x2B51, -+0x080F, -+0xFF00, -+0x2BEF, -+0x080F, -+0x00FF, -+0x2BEF, -+0x33AF, -+0x1975, -+0x2B4D, -+0x1976, -+0x2B4E, -+0x197A, -+0x2B52, -+0x080F, -+0xFF00, -+0x2BF0, -+0x080F, -+0x00FF, -+0x2BF0, -+0x33AF, -+0x01A8, -+0x0100, -+0x1B4F, -+0x29AD, -+0x01AF, -+0x0010, -+0xD9B6, -+0x1B50, -+0x29AD, -+0x01AF, -+0x0012, -+0xD9B6, -+0x1B41, -+0x29AD, -+0x01AF, -+0x0002, -+0xD9B6, -+0x1B42, -+0x29AD, -+0x01AF, -+0x0003, -+0xD9B6, -+0x33FE, -+0x0C3F, -+0x804B, -+0xD1AC, -+0x01B3, -+0x0077, -+0xD100, -+0xD1A8, -+0xD1AE, -+0x8646, -+0x33FE, -+0x0C3F, -+0x804D, -+0xD1A8, -+0xD9B6, -+0x080F, -+0x0400, -+0xD185, -+0x33AF, -+0x9006, -+0x0804, -+0x0040, -+0x5C03, -+0xA650, -+0x8653, -+0x0CE1, -+0x7080, -+0x8655, -+0x0CC1, -+0x7080, -+0x6660, -+0x0C42, -+0x5443, -+0xB65B, -+0x6260, -+0x8678, -+0xA669, -+0x080E, -+0x7FFF, -+0x198A, -+0x33AE, -+0x31A2, -+0x4022, -+0x080E, -+0x7FFF, -+0x1986, -+0x33AE, -+0x426D, -+0x55A2, -+0x8678, -+0x080E, -+0x7FFF, -+0x1986, -+0x33AE, -+0x31A2, -+0x4022, -+0x426D, -+0x55A2, -+0x31A2, -+0x080E, -+0x7FFF, -+0x198A, -+0x33AE, -+0x402D, -+0x544D, -+0xB680, -+0x0C02, -+0x55A2, -+0x31A5, -+0x380D, -+0x3802, -+0x548D, -+0x8686, -+0x31A5, -+0x3802, -+0xA684, -+0x8691, -+0x380D, -+0x508D, -+0x35A0, -+0x29AD, -+0xD9B6, -+0x5C03, -+0xA68E, -+0x0C37, -+0x700F, -+0x8693, -+0x0C17, -+0x700F, -+0x8693, -+0x31A5, -+0x3802, -+0x4224, -+0x5C21, -+0xA655, -+0x0C81, -+0x6660, -+0x0C44, -+0x5483, -+0xB69D, -+0x6260, -+0x86BA, -+0xA6AB, -+0x080E, -+0x7FFF, -+0x198A, -+0x33AE, -+0x31A4, -+0x4024, -+0x080E, -+0x7FFF, -+0x1986, -+0x33AE, -+0x426D, -+0x55A4, -+0x86BA, -+0x080E, -+0x7FFF, -+0x1986, -+0x33AE, -+0x31A4, -+0x4024, -+0x426D, -+0x55A4, -+0x31A4, -+0x080E, -+0x7FFF, -+0x198A, -+0x33AE, -+0x402D, -+0x548D, -+0x31A4, -+0xB6CD, -+0x0C04, -+0x55A4, -+0x31A4, -+0x54A4, -+0xB6C3, -+0x3085, -+0x3802, -+0x32ED, -+0xA6C8, -+0x380D, -+0x5C2D, -+0x86CA, -+0x380D, -+0x5C4D, -+0x31A4, -+0xB6DB, -+0x86EF, -+0x54A4, -+0xB6D1, -+0x3085, -+0x3802, -+0x32ED, -+0xA6D6, -+0x380D, -+0x582D, -+0x86D8, -+0x380D, -+0x584D, -+0x31A4, -+0x430D, -+0xA6EF, -+0x5C21, -+0xA6E4, -+0x3804, -+0x5482, -+0xA6E1, -+0x86EF, -+0x3440, -+0x304D, -+0x86E6, -+0x3480, -+0x308D, -+0x29AD, -+0xD9B6, -+0x5C03, -+0xA6EC, -+0x700F, -+0x86ED, -+0x700F, -+0x5C01, -+0xA697, -+0x33DF, -+0x9007, -+0x1B36, -+0xA709, -+0xD35E, -+0x038D, -+0x0030, -+0xD10D, -+0x010D, -+0x0002, -+0x0306, -+0x000C, -+0x0C2E, -+0x1919, -+0x33AE, -+0xA700, -+0x86FB, -+0x0306, -+0x0008, -+0x0C2E, -+0x1919, -+0x33AE, -+0xA702, -+0x0305, -+0x000C, -+0xD10D, -+0x038D, -+0x0030, -+0x1B38, -+0xA711, -+0x080F, -+0x0080, -+0xD37B, -+0x33AF, -+0xD38D, -+0x1B38, -+0xA716, -+0x0C6C, -+0x871E, -+0x1B34, -+0xA71D, -+0x080E, -+0x01E0, -+0x131C, -+0x33AE, -+0x871E, -+0x0C0C, -+0x33FE, -+0x0C3F, -+0x8946, -+0x1B49, -+0x2B47, -+0x038D, -+0x0030, -+0xD1A8, -+0xD161, -+0x0162, -+0x0042, -+0x0163, -+0x0060, -+0xD164, -+0xD165, -+0x0167, -+0x21A2, -+0x1BEE, -+0x2BCD, -+0x1BED, -+0x2BCC, -+0x13CD, -+0x1B52, -+0x518D, -+0x31AC, -+0x430D, -+0xA73B, -+0x318D, -+0x873D, -+0x080D, -+0x00FF, -+0x31A1, -+0x080F, -+0xFF00, -+0x2969, -+0x33AF, -+0x13CC, -+0x1B51, -+0x518D, -+0x31AC, -+0x430D, -+0xA74A, -+0x318D, -+0x874C, -+0x080D, -+0x00FF, -+0x31A1, -+0x080F, -+0x00FF, -+0x2969, -+0x33AF, -+0x0181, -+0xFFFF, -+0x0182, -+0x3C02, -+0x0183, -+0x0800, -+0x0184, -+0x7060, -+0x0185, -+0x2402, -+0x1B67, -+0x2980, -+0x1B68, -+0x2960, -+0x1B69, -+0x2966, -+0x1B6A, -+0x2968, -+0x1B36, -+0xA76B, -+0x0807, -+0x076A, -+0x33FE, -+0x0C1F, -+0x89C5, -+0x6C00, -+0xD162, -+0x0163, -+0x001F, -+0x0182, -+0x3C23, -+0x0183, -+0x0087, -+0x0184, -+0x7068, -+0x0185, -+0x247C, -+0x1B6B, -+0x2980, -+0x1B6C, -+0x2960, -+0x1B6D, -+0x2966, -+0x1B6E, -+0x2968, -+0x1B36, -+0xA781, -+0x6C00, -+0x0182, -+0x3C02, -+0x0183, -+0x0800, -+0x0184, -+0x7060, -+0x0185, -+0x2402, -+0x0162, -+0x0042, -+0x0163, -+0x0060, -+0x0167, -+0x39C0, -+0x1B7C, -+0x2980, -+0x1B7D, -+0x2960, -+0x1B7E, -+0x2966, -+0x1B7F, -+0x2968, -+0x1B36, -+0xA7E0, -+0x0807, -+0x079E, -+0x33FE, -+0x0C1F, -+0x89C5, -+0x6C00, -+0x080E, -+0x4000, -+0x1B6F, -+0x33AE, -+0xA7E0, -+0x080E, -+0x03C0, -+0x196C, -+0x33AE, -+0x5CED, -+0xB7E0, -+0x0180, -+0x01FF, -+0x080F, -+0x03E0, -+0x0182, -+0x0002, -+0x33AF, -+0x6620, -+0xB7B4, -+0x87E0, -+0xA7B6, -+0x87E0, -+0x080F, -+0x3FFF, -+0xD160, -+0x33AF, -+0x080F, -+0x0038, -+0x0166, -+0x0005, -+0x33AF, -+0x080E, -+0x03C0, -+0x196C, -+0x33AE, -+0x402D, -+0x31A0, -+0x080E, -+0x003F, -+0x196C, -+0x33AE, -+0xA7CC, -+0x5820, -+0x87CD, -+0x5840, -+0x31A0, -+0x080F, -+0x7C00, -+0x2167, -+0x080F, -+0x03E0, -+0x2167, -+0x33AF, -+0x1169, -+0x3181, -+0x080F, -+0x1000, -+0xD166, -+0x33AF, -+0x0169, -+0xFFFF, -+0x6C00, -+0x302D, -+0x2969, -+0x1969, -+0x2BF7, -+0x080E, -+0x0020, -+0x1B6F, -+0x33AE, -+0xA7EA, -+0x33FE, -+0x0C3F, -+0x8BA3, -+0x080F, -+0x7C00, -+0xD3F6, -+0x33AF, -+0xD3F8, -+0xD3F9, -+0xD3FA, -+0x080E, -+0x8000, -+0x1BF6, -+0x33AE, -+0xA891, -+0x0CC0, -+0x0D61, -+0x0C22, -+0x0C23, -+0x0804, -+0x00F5, -+0x0807, -+0x0801, -+0x33FE, -+0x0C3F, -+0x89E6, -+0x31B8, -+0x080F, -+0xFF00, -+0x2BF8, -+0x33AF, -+0x0CC0, -+0x0D61, -+0x0C22, -+0x0C23, -+0x0804, -+0x00F5, -+0x0807, -+0x0811, -+0x33FE, -+0x0C3F, -+0x8A57, -+0x31B9, -+0x080F, -+0x00FF, -+0x2BF8, -+0x33AF, -+0x0C40, -+0x0D61, -+0x0C22, -+0x0C23, -+0x0804, -+0x00F5, -+0x0807, -+0x0821, -+0x33FE, -+0x0C3F, -+0x89E6, -+0x31BA, -+0x080F, -+0xFF00, -+0x2BF9, -+0x33AF, -+0x0C40, -+0x0D61, -+0x0C22, -+0x0C23, -+0x0804, -+0x00F5, -+0x0807, -+0x0831, -+0x33FE, -+0x0C3F, -+0x8A57, -+0x31BB, -+0x080F, -+0x00FF, -+0x2BF9, -+0x33AF, -+0x0807, -+0x083B, -+0x33FE, -+0x0C3F, -+0x8AC8, -+0x080E, -+0x0400, -+0x1BF6, -+0x33AE, -+0xA841, -+0x8891, -+0x080E, -+0x6000, -+0x1BF6, -+0x33AE, -+0x5C2D, -+0xA848, -+0x8868, -+0x0CC0, -+0x0C61, -+0x0D02, -+0x0C03, -+0x0804, -+0x00FF, -+0x0807, -+0x0853, -+0x33FE, -+0x0C3F, -+0x89E6, -+0x31B8, -+0x080F, -+0xFF00, -+0x2BFA, -+0x33AF, -+0x0C80, -+0x0D61, -+0x0D02, -+0x0C03, -+0x0C04, -+0x0807, -+0x0862, -+0x33FE, -+0x0C3F, -+0x89E6, -+0x31BA, -+0x080F, -+0x00FF, -+0x2BFA, -+0x33AF, -+0x8887, -+0x0CC0, -+0x0C61, -+0x0D02, -+0x0C03, -+0x0804, -+0x00FF, -+0x0807, -+0x0873, -+0x33FE, -+0x0C3F, -+0x8A57, -+0x31B9, -+0x080F, -+0xFF00, -+0x2BFA, -+0x33AF, -+0x0C80, -+0x0D61, -+0x0D02, -+0x0C03, -+0x0C04, -+0x0807, -+0x0882, -+0x33FE, -+0x0C3F, -+0x8A57, -+0x31BB, -+0x080F, -+0x00FF, -+0x2BFA, -+0x33AF, -+0x0807, -+0x088C, -+0x33FE, -+0x0C3F, -+0x8B11, -+0x0807, -+0x0891, -+0x33FE, -+0x0C3F, -+0x8B34, -+0x080E, -+0x0400, -+0x1BF6, -+0x33AE, -+0xA8E9, -+0x0181, -+0xFFFF, -+0x0182, -+0x3C06, -+0x0183, -+0x0800, -+0x0184, -+0x7060, -+0x0185, -+0x247E, -+0x0161, -+0x0009, -+0x0162, -+0x00C2, -+0x0163, -+0x7F80, -+0xD164, -+0xD165, -+0x0167, -+0x21A2, -+0x1BF7, -+0x2969, -+0x1BE0, -+0x2980, -+0x1BE1, -+0x2960, -+0x1BE2, -+0x2966, -+0x1BE3, -+0x2968, -+0x1B37, -+0xA8E9, -+0x0807, -+0x08BB, -+0x33FE, -+0x0C1F, -+0x89C5, -+0x6C00, -+0x080E, -+0xFF00, -+0x197B, -+0x33AE, -+0x31A1, -+0x080E, -+0x4000, -+0x1963, -+0x33AE, -+0xA8C7, -+0x88D0, -+0x0807, -+0x08CA, -+0x8D52, -+0x31A2, -+0xA8CE, -+0x5461, -+0x88CF, -+0x5061, -+0x31A1, -+0x1351, -+0x302D, -+0x558D, -+0x2BCC, -+0x080E, -+0x00FF, -+0x197B, -+0x33AE, -+0x31A1, -+0x080E, -+0x4000, -+0x1963, -+0x33AE, -+0xA8DF, -+0x88E5, -+0x304D, -+0xA8E3, -+0x5461, -+0x88E4, -+0x5061, -+0x31A1, -+0x1352, -+0x302D, -+0x558D, -+0x2BCD, -+0x33FE, -+0x0C3F, -+0x86CB, -+0x0182, -+0x3C06, -+0x0183, -+0x0800, -+0x0185, -+0x247E, -+0x0163, -+0x7F80, -+0x1BE4, -+0x2980, -+0x1BE5, -+0x2960, -+0x1BE6, -+0x2966, -+0x1BE7, -+0x2968, -+0x080E, -+0x0400, -+0x1BF6, -+0x33AE, -+0xA902, -+0x891D, -+0x080F, -+0x0F80, -+0x0163, -+0x001E, -+0x33AF, -+0x080E, -+0x0800, -+0x1BF6, -+0x33AE, -+0xA912, -+0x080E, -+0x1000, -+0x1BF6, -+0x33AE, -+0xA918, -+0x891D, -+0x080F, -+0x03E0, -+0x0182, -+0x0002, -+0x33AF, -+0x891D, -+0x080F, -+0x03E0, -+0x0182, -+0x0006, -+0x33AF, -+0x1B37, -+0xA962, -+0x13CD, -+0x410C, -+0x1BCC, -+0x518D, -+0x31A1, -+0x1352, -+0x410C, -+0x502C, -+0x31A2, -+0x1352, -+0x410C, -+0x502C, -+0x31A2, -+0x1351, -+0x504C, -+0x2969, -+0x0807, -+0x0934, -+0x33FE, -+0x0C1F, -+0x89C5, -+0x6C00, -+0x080E, -+0xFF00, -+0x197B, -+0x33AE, -+0x31A1, -+0x080E, -+0x4000, -+0x1963, -+0x33AE, -+0xA940, -+0x8949, -+0x0807, -+0x0943, -+0x8D52, -+0x31A2, -+0xA947, -+0x5461, -+0x8948, -+0x5061, -+0x31A1, -+0x1351, -+0x302D, -+0x558D, -+0x2BCC, -+0x080E, -+0x00FF, -+0x197B, -+0x33AE, -+0x31A1, -+0x080E, -+0x4000, -+0x1963, -+0x33AE, -+0xA958, -+0x895E, -+0x304D, -+0xA95C, -+0x5461, -+0x895D, -+0x5061, -+0x31A1, -+0x1352, -+0x302D, -+0x558D, -+0x2BCD, -+0x080E, -+0x0020, -+0x1B6F, -+0x33AE, -+0xA96A, -+0x33FE, -+0x0C3F, -+0x8C25, -+0x080E, -+0x0020, -+0x1B6F, -+0x33AE, -+0xA976, -+0x33FE, -+0x0C3F, -+0x8D47, -+0x2BCB, -+0x13CB, -+0x3180, -+0x2311, -+0x33FE, -+0x0C3F, -+0x80F0, -+0x038D, -+0x0030, -+0xDB5E, -+0x1B38, -+0xA982, -+0x080F, -+0x0080, -+0xDB7B, -+0x33AF, -+0xD10D, -+0x010D, -+0x0002, -+0x0306, -+0x000C, -+0x0C2E, -+0x1919, -+0x33AE, -+0xA98C, -+0x8987, -+0xD306, -+0x0C2E, -+0x1919, -+0x33AE, -+0xA98D, -+0x0305, -+0x000C, -+0xD10D, -+0x8998, -+0x038D, -+0x0030, -+0xDB5E, -+0xD38D, -+0xDB10, -+0x1B86, -+0xA99D, -+0x899A, -+0xD310, -+0xDB8C, -+0x080F, -+0x0400, -+0xD185, -+0x33AF, -+0x9006, -+0x038D, -+0x0029, -+0x1BC5, -+0xA9A9, -+0x89BE, -+0x1B5E, -+0xA9AC, -+0x89BE, -+0x0D0E, -+0x1913, -+0x33AE, -+0xA9AC, -+0x080E, -+0x01FC, -+0x1BF6, -+0x33AE, -+0x31B7, -+0xAA12, -+0x89BB, -+0x0C2D, -+0x55B7, -+0x31B7, -+0xAA1C, -+0x0C4F, -+0xDBF6, -+0x33AF, -+0x080F, -+0x0400, -+0xD185, -+0x33AF, -+0x8A77, -+0x0167, -+0x21A2, -+0x1B33, -+0xA9DD, -+0x0C21, -+0x0C42, -+0x13F2, -+0x542C, -+0xA9D4, -+0x0181, -+0xAAAA, -+0x080F, -+0x3C00, -+0x0182, -+0x000A, -+0x33AF, -+0x89DD, -+0x544C, -+0xA9DD, -+0x0181, -+0x5555, -+0x080F, -+0x3C00, -+0x0182, -+0x0005, -+0x33AF, -+0x33DF, -+0x9007, -+0x038D, -+0x0029, -+0x1BC5, -+0xA9E6, -+0x1BC6, -+0xA9E6, -+0x8A09, -+0x7FFF, -+0x0D0E, -+0x1913, -+0x33AE, -+0xA9E7, -+0x1BC5, -+0xA9EE, -+0x89F1, -+0x0806, -+0x09F1, -+0x8A0F, -+0x1BC6, -+0xA9F4, -+0x8A09, -+0x1BF1, -+0x31BC, -+0x2BCC, -+0x430D, -+0x2BCD, -+0x0806, -+0x0A03, -+0x080E, -+0x0020, -+0x1BF3, -+0x33AE, -+0xAA03, -+0x33FE, -+0x0C3F, -+0x82BD, -+0x0806, -+0x0A08, -+0x1B30, -+0xAA08, -+0x8AB4, -+0x8EED, -+0xD38D, -+0x080F, -+0x0400, -+0xD185, -+0x33AF, -+0x807A, -+0x1B59, -+0xAA12, -+0x8A09, -+0x0C2F, -+0xDB75, -+0x33AF, -+0x0C6F, -+0x010D, -+0x0002, -+0x33AF, -+0xD3A6, -+0x03A6, -+0x000A, -+0x0180, -+0x7D00, -+0xD981, -+0xD182, -+0xD183, -+0xD184, -+0x0185, -+0x2408, -+0x01AC, -+0xA080, -+0x01AF, -+0x0002, -+0x0800, -+0x0341, -+0x0C01, -+0x0C62, -+0xD9AE, -+0x0807, -+0x0A32, -+0x1B3A, -+0xAA32, -+0x8A82, -+0x01AC, -+0xA0C0, -+0x01AF, -+0x0003, -+0x0800, -+0x0342, -+0x0C01, -+0x0C62, -+0x0807, -+0x0A3F, -+0x1B3A, -+0xAA3F, -+0x8A82, -+0x0C4E, -+0x1BF6, -+0x33AE, -+0xAA45, -+0x1B5E, -+0xA9B7, -+0x01AC, -+0x2000, -+0x0180, -+0x7D00, -+0x0181, -+0x5555, -+0x0182, -+0x1446, -+0x0183, -+0x010D, -+0x0184, -+0x2800, -+0x0185, -+0x6410, -+0xD1AC, -+0x01AF, -+0x0014, -+0x0800, -+0x0345, -+0x0C21, -+0x0C62, -+0x0807, -+0x0A5F, -+0x1B39, -+0xAA5F, -+0x8A82, -+0x0180, -+0x7D00, -+0x0181, -+0xAAAA, -+0x0182, -+0x2846, -+0x0183, -+0x010D, -+0x0184, -+0x2800, -+0x0185, -+0x6410, -+0xD1AC, -+0x01AF, -+0x0015, -+0x0800, -+0x0346, -+0x0C21, -+0x0C62, -+0x0807, -+0x0A77, -+0x1B39, -+0xAA77, -+0x8A82, -+0xD1AE, -+0xD1AC, -+0xD3A6, -+0x7000, -+0x0C6F, -+0xD10D, -+0x33AF, -+0x0C2F, -+0xD375, -+0x33AF, -+0x9006, -+0x380D, -+0x29AD, -+0xD9B6, -+0x7080, -+0x667C, -+0x302D, -+0xAA8F, -+0x080E, -+0x7FFF, -+0x198A, -+0x1186, -+0x33AE, -+0x8A94, -+0x080E, -+0x7FFF, -+0x198B, -+0x1186, -+0x33AE, -+0x402D, -+0x31A3, -+0x3184, -+0x3185, -+0x304D, -+0xAA9B, -+0x8A9E, -+0x4225, -+0x5C22, -+0x8A98, -+0x5085, -+0x546D, -+0xBAA2, -+0x8AAB, -+0x54A4, -+0x55A3, -+0xBAA6, -+0x8AA7, -+0x9007, -+0x5E20, -+0xBAB0, -+0x3580, -+0x9007, -+0x5A20, -+0x31A2, -+0x430D, -+0xAAA9, -+0x304D, -+0x29AD, -+0xD9B6, -+0x700F, -+0x9007, -+0x1B5E, -+0xAAB7, -+0x8A09, -+0x080E, -+0x8000, -+0x1BEB, -+0x33AE, -+0xAB44, -+0x0180, -+0x7D00, -+0x0181, -+0xFFFF, -+0x0182, -+0x3C23, -+0x0183, -+0x0087, -+0x0184, -+0x3068, -+0x0185, -+0x647C, -+0xD160, -+0xD161, -+0xD162, -+0x0163, -+0x001F, -+0x0164, -+0x000A, -+0xD165, -+0x0166, -+0x7800, -+0x0167, -+0x21A2, -+0xD168, -+0x0169, -+0xB7B7, -+0x0D0C, -+0x080E, -+0x03E0, -+0x196D, -+0x33AE, -+0x55AC, -+0xAB42, -+0x0180, -+0x1964, -+0x6620, -+0x0C00, -+0x0C01, -+0x080E, -+0x7FFF, -+0x1186, -+0x33AE, -+0x080D, -+0x0100, -+0x518D, -+0x31AC, -+0x0C2E, -+0x1963, -+0x33AE, -+0xAAF0, -+0x8AF8, -+0x080E, -+0x7FFF, -+0x1989, -+0x33AE, -+0x500D, -+0x31A0, -+0x5181, -+0x31A1, -+0x0C4E, -+0x1963, -+0x33AE, -+0xAAFD, -+0x8B05, -+0x080E, -+0x7FFF, -+0x198A, -+0x33AE, -+0x500D, -+0x31A0, -+0x5181, -+0x31A1, -+0x0C8E, -+0x1963, -+0x33AE, -+0xAB0A, -+0x8B12, -+0x080E, -+0x7FFF, -+0x198B, -+0x33AE, -+0x500D, -+0x31A0, -+0x5181, -+0x31A1, -+0x0D0E, -+0x1963, -+0x33AE, -+0xAB17, -+0x8B1F, -+0x080E, -+0x7FFF, -+0x198C, -+0x33AE, -+0x500D, -+0x31A0, -+0x5181, -+0x31A1, -+0x0E0E, -+0x1963, -+0x33AE, -+0xAB24, -+0x8B2C, -+0x080E, -+0x7FFF, -+0x198D, -+0x33AE, -+0x500D, -+0x31A0, -+0x5181, -+0x31A1, -+0x422D, -+0x540D, -+0xBB44, -+0x080F, -+0x03FF, -+0x0182, -+0x0084, -+0x33AF, -+0x0C2F, -+0xD183, -+0x33AF, -+0x080F, -+0x0020, -+0xD184, -+0x33AF, -+0x0FEF, -+0xD963, -+0x33AF, -+0x0180, -+0x7D00, -+0x6C00, -+0x8B44, -+0xBB44, -+0x6C00, -+0x13EE, -+0x319A, -+0x410C, -+0x1BED, -+0x31BB, -+0x518D, -+0x31BC, -+0x1B3C, -+0xAC2C, -+0x0180, -+0x07FF, -+0x0181, -+0xFFFF, -+0x0182, -+0x3C06, -+0x0183, -+0x0800, -+0x0184, -+0x3060, -+0x0185, -+0x6402, -+0x0160, -+0x0C07, -+0xD161, -+0x0162, -+0x0042, -+0x0163, -+0x3000, -+0xD164, -+0xD165, -+0x0166, -+0x7828, -+0x0167, -+0x21A2, -+0xD168, -+0x0807, -+0x0B6C, -+0x33FE, -+0x0C1F, -+0x89C5, -+0x0FEF, -+0x0182, -+0x0002, -+0x33AF, -+0x1352, -+0x1BEE, -+0x518D, -+0x31AC, -+0x430D, -+0xAB78, -+0x318D, -+0x8B7A, -+0x080D, -+0x00FF, -+0x31A1, -+0x080F, -+0xFF00, -+0x2969, -+0x33AF, -+0x1351, -+0x1BED, -+0x518D, -+0x31AC, -+0x430D, -+0xAB87, -+0x318D, -+0x8B89, -+0x080D, -+0x00FF, -+0x31A1, -+0x080F, -+0x00FF, -+0x2969, -+0x33AF, -+0x6C00, -+0x1351, -+0x080E, -+0xFF00, -+0x197B, -+0x33AE, -+0x558D, -+0xBB98, -+0x0C1B, -+0x8B99, -+0x31BB, -+0x1352, -+0x080E, -+0x00FF, -+0x197B, -+0x33AE, -+0x558D, -+0xBBA2, -+0x0C1A, -+0x8BA3, -+0x31BA, -+0x0180, -+0x7D00, -+0x0181, -+0xFFFF, -+0x0182, -+0x3C02, -+0x0183, -+0x0800, -+0x0184, -+0x3060, -+0x0185, -+0x6402, -+0xD160, -+0xD161, -+0x0162, -+0x0042, -+0x0163, -+0x0060, -+0x0164, -+0x00D0, -+0xD165, -+0x0166, -+0x7800, -+0x0167, -+0x21A2, -+0xD168, -+0x13CD, -+0x1B52, -+0x518D, -+0x31AC, -+0x430D, -+0xABC5, -+0x318D, -+0x8BC7, -+0x080D, -+0x00FF, -+0x31A1, -+0x080F, -+0xFF00, -+0x2969, -+0x33AF, -+0x13CC, -+0x1B51, -+0x518D, -+0x31AC, -+0x430D, -+0xABD4, -+0x318D, -+0x8BD6, -+0x080D, -+0x00FF, -+0x31A1, -+0x080F, -+0x00FF, -+0x2969, -+0x33AF, -+0x0807, -+0x0BE0, -+0x33FE, -+0x0C1F, -+0x89C5, -+0xD160, -+0x080F, -+0x0038, -+0x0166, -+0x0005, -+0x080F, -+0x1000, -+0xD166, -+0x080F, -+0x0E00, -+0x0166, -+0x0004, -+0x33AF, -+0x1BED, -+0x31A2, -+0x545B, -+0xBC0E, -+0x080E, -+0x03C0, -+0x196C, -+0x33AE, -+0x402D, -+0x31A0, -+0x080E, -+0x003F, -+0x196C, -+0x33AE, -+0xABFE, -+0x5820, -+0x8BFF, -+0x5840, -+0x31A0, -+0x0DC4, -+0x5404, -+0xBC04, -+0x0DC0, -+0x080F, -+0x7C00, -+0x2167, -+0x080F, -+0x03E0, -+0x2167, -+0x33AF, -+0x0169, -+0xFFFF, -+0x8C2B, -+0x1BED, -+0x590D, -+0x576D, -+0xBC2C, -+0x080E, -+0x03C0, -+0x196C, -+0x33AE, -+0x402D, -+0x31A0, -+0x080E, -+0x003F, -+0x196C, -+0x33AE, -+0xAC21, -+0x5C20, -+0xBC20, -+0x0C0D, -+0x31A0, -+0x080F, -+0x7C00, -+0x2167, -+0x080F, -+0x03E0, -+0x2167, -+0x0FEF, -+0x2167, -+0x33AF, -+0xD169, -+0x6C00, -+0x1B3B, -+0xAC7E, -+0x0180, -+0x07FF, -+0x0181, -+0xFFFF, -+0x0182, -+0x3C06, -+0x0183, -+0x0800, -+0x0184, -+0x3060, -+0x0185, -+0x6402, -+0x0160, -+0x0C07, -+0xD161, -+0x0162, -+0x0042, -+0x0163, -+0x3000, -+0xD164, -+0xD165, -+0x0166, -+0x7828, -+0x0167, -+0x21A2, -+0xD168, -+0x1352, -+0x519A, -+0x31AC, -+0x430D, -+0xAC4F, -+0x318D, -+0x8C51, -+0x080D, -+0x00FF, -+0x31A1, -+0x080F, -+0xFF00, -+0x2969, -+0x33AF, -+0x1351, -+0x519B, -+0x31AC, -+0x430D, -+0xAC5D, -+0x318D, -+0x8C5F, -+0x080D, -+0x00FF, -+0x31A1, -+0x080F, -+0x00FF, -+0x2969, -+0x33AF, -+0x0807, -+0x0C69, -+0x33FE, -+0x0C1F, -+0x89C5, -+0x6C00, -+0x1351, -+0x080E, -+0xFF00, -+0x197B, -+0x33AE, -+0x558D, -+0xBC73, -+0x0C1B, -+0x8C74, -+0x31BB, -+0x1352, -+0x080E, -+0x00FF, -+0x197B, -+0x33AE, -+0x558D, -+0xBC7D, -+0x0C1A, -+0x8C7E, -+0x31BA, -+0x080E, -+0x0040, -+0x1BF3, -+0x33AE, -+0xACB2, -+0x0180, -+0x7D00, -+0x0181, -+0xFFFF, -+0x0182, -+0x3C06, -+0x0183, -+0x0800, -+0x0184, -+0x3060, -+0x0185, -+0x647C, -+0xD160, -+0x0161, -+0x0009, -+0x0162, -+0x0042, -+0x0163, -+0x0F00, -+0x0164, -+0xA000, -+0x0165, -+0x0999, -+0x0166, -+0x7800, -+0x0167, -+0x21A2, -+0xD168, -+0x334C, -+0x410C, -+0x336D, -+0x518D, -+0x31BC, -+0x1352, -+0x410C, -+0x3381, -+0x502C, -+0x31A2, -+0x1351, -+0x504C, -+0x2969, -+0x0807, -+0x0CB1, -+0x33FE, -+0x0C1F, -+0x89C5, -+0x6C00, -+0x196B, -+0x2B5A, -+0x196D, -+0x2B5C, -+0x196C, -+0x2B5B, -+0x196E, -+0x2B5D, -+0x196F, -+0x2B60, -+0x1970, -+0x2B61, -+0x1971, -+0x2B62, -+0x1972, -+0x2B63, -+0x8CC3, -+0x33FE, -+0x0C3F, -+0x8000, -+0x9006, -+0x080E, -+0x3000, -+0x1913, -+0x080E, -+0xFFFF, -+0xACCE, -+0x9006, -+0x19B3, -+0x0800, -+0x0077, -+0x540D, -+0xACD4, -+0x8D51, -+0xD9AE, -+0x01AF, -+0x0010, -+0x0800, -+0x0348, -+0x0801, -+0x0347, -+0x0802, -+0x034B, -+0x3C40, -+0x0807, -+0x0CE1, -+0x8D52, -+0x0807, -+0x0CE5, -+0x0C04, -+0x8D64, -+0x01AF, -+0x0012, -+0x0800, -+0x0348, -+0x0801, -+0x0348, -+0x0802, -+0x034D, -+0x3C40, -+0x0807, -+0x0CF1, -+0x8D52, -+0x0807, -+0x0CF5, -+0x0C04, -+0x8D64, -+0x01AF, -+0x0011, -+0x0800, -+0x0348, -+0x0801, -+0x0347, -+0x0802, -+0x034C, -+0x3C40, -+0x0807, -+0x0D01, -+0x8D52, -+0x0807, -+0x0D05, -+0x0C24, -+0x8D64, -+0x01AF, -+0x0013, -+0x0800, -+0x0348, -+0x0801, -+0x0348, -+0x0802, -+0x034E, -+0x3C40, -+0x0807, -+0x0D11, -+0x8D52, -+0x0807, -+0x0D15, -+0x0C24, -+0x8D64, -+0x19B3, -+0x31A4, -+0x0805, -+0x01EE, -+0x54A4, -+0xAD1C, -+0x8D3F, -+0x0805, -+0x01CC, -+0x54A4, -+0xAD21, -+0x8D41, -+0x0805, -+0x0144, -+0x54A4, -+0xAD26, -+0x8D43, -+0x0805, -+0x0188, -+0x54A4, -+0xAD2B, -+0x8D46, -+0x0805, -+0x0100, -+0x54A4, -+0xAD30, -+0x8D48, -+0x0805, -+0x0111, -+0x54A4, -+0xAD35, -+0x8D4A, -+0x0805, -+0x0155, -+0x54A4, -+0xAD3A, -+0x8D4C, -+0x0805, -+0x0177, -+0x54A4, -+0xAD4E, -+0x8D4E, -+0x01B3, -+0x01CC, -+0x01B3, -+0x0144, -+0x01B3, -+0x0155, -+0x8D4C, -+0x01B3, -+0x0100, -+0x01B3, -+0x0111, -+0x01B3, -+0x0155, -+0x01B3, -+0x0177, -+0x01B3, -+0x0077, -+0xD1AE, -+0x9006, -+0x080E, -+0x1FE0, -+0x196E, -+0x33AE, -+0x31A3, -+0x080E, -+0x1000, -+0x196E, -+0x33AE, -+0x31A4, -+0xAD5E, -+0x8D62, -+0x080D, -+0x0100, -+0x546D, -+0x31A3, -+0x308D, -+0x9007, -+0xAD68, -+0x308D, -+0xAD72, -+0x8D6B, -+0x308D, -+0xAD6B, -+0x8D72, -+0x3805, -+0x5065, -+0x31A4, -+0x430D, -+0xAD79, -+0x308D, -+0x8D76, -+0x3805, -+0x5465, -+0xBD76, -+0x8D79, -+0x3C02, -+0x35A1, -+0x8D7A, -+0x384D, -+0x29AD, -+0xD9B6, -+0x9007, -+0x01AF, -+0x0010, -+0x01AD, -+0x0080, -+0xD9B6, -+0x01AF, -+0x0011, -+0xD1AD, -+0xD9B6, -+0x01AF, -+0x0016, -+0x01AD, -+0x00FF, -+0xD9B6, -+0x01AF, -+0x0014, -+0xD1AD, -+0xD9B6, -+0x01AF, -+0x0012, -+0xD1AD, -+0xD9B6, -+0x01AF, -+0x0013, -+0xD1AD, -+0xD9B6, -+0x01AF, -+0x0018, -+0x01AD, -+0x00FF, -+0xD9B6, -+0x01AF, -+0x0015, -+0xD1AD, -+0xD9B6, -+0x9007, -+0x01AF, -+0x0010, -+0xD1AD, -+0xD9B6, -+0x01AF, -+0x0011, -+0x01AD, -+0x0080, -+0xD9B6, -+0x01AF, -+0x0016, -+0x01AD, -+0x00FF, -+0xD9B6, -+0x01AF, -+0x0014, -+0xD1AD, -+0xD9B6, -+0x01AF, -+0x0012, -+0x01AD, -+0x00FF, -+0xD9B6, -+0x01AF, -+0x0013, -+0x01AD, -+0x00FF, -+0xD9B6, -+0x01AF, -+0x0018, -+0x01AD, -+0x00FF, -+0xD9B6, -+0x01AF, -+0x0015, -+0xD1AD, -+0xD9B6, -+0x9007, -+0x01AF, -+0x0010, -+0xD1AD, -+0xD9B6, -+0x01AF, -+0x0011, -+0x01AD, -+0x00FF, -+0xD9B6, -+0x01AF, -+0x0016, -+0x01AD, -+0x0080, -+0xD9B6, -+0x01AF, -+0x0014, -+0xD1AD, -+0xD9B6, -+0x01AF, -+0x0012, -+0xD1AD, -+0xD9B6, -+0x01AF, -+0x0013, -+0x01AD, -+0x00FF, -+0xD9B6, -+0x01AF, -+0x0018, -+0x01AD, -+0x00FF, -+0xD9B6, -+0x01AF, -+0x0015, -+0xD1AD, -+0xD9B6, -+0x9007, -+0x01AF, -+0x0010, -+0xD1AD, -+0xD9B6, -+0x01AF, -+0x0011, -+0x01AD, -+0x00FF, -+0xD9B6, -+0x01AF, -+0x0016, -+0x01AD, -+0x00FF, -+0xD9B6, -+0x01AF, -+0x0014, -+0x01AD, -+0x0080, -+0xD9B6, -+0x01AF, -+0x0012, -+0xD1AD, -+0xD9B6, -+0x01AF, -+0x0013, -+0xD1AD, -+0xD9B6, -+0x01AF, -+0x0018, -+0x01AD, -+0x00FF, -+0xD9B6, -+0x01AF, -+0x0015, -+0xD1AD, -+0xD9B6, -+0x9007, -+0x01AF, -+0x0010, -+0xD1AD, -+0xD9B6, -+0x01AF, -+0x0011, -+0xD1AD, -+0xD9B6, -+0x01AF, -+0x0016, -+0x01AD, -+0x00FF, -+0xD9B6, -+0x01AF, -+0x0014, -+0xD1AD, -+0xD9B6, -+0x01AF, -+0x0012, -+0x01AD, -+0x0080, -+0xD9B6, -+0x01AF, -+0x0013, -+0xD1AD, -+0xD9B6, -+0x01AF, -+0x0018, -+0x01AD, -+0x00FF, -+0xD9B6, -+0x01AF, -+0x0015, -+0xD1AD, -+0xD9B6, -+0x9007, -+0x01AF, -+0x0010, -+0x01AD, -+0x00FF, -+0xD9B6, -+0x01AF, -+0x0011, -+0x01AD, -+0x00FF, -+0xD9B6, -+0x01AF, -+0x0016, -+0x01AD, -+0x00FF, -+0xD9B6, -+0x01AF, -+0x0014, -+0xD1AD, -+0xD9B6, -+0x01AF, -+0x0012, -+0xD1AD, -+0xD9B6, -+0x01AF, -+0x0013, -+0x01AD, -+0x0080, -+0xD9B6, -+0x01AF, -+0x0018, -+0x01AD, -+0x00FF, -+0xD9B6, -+0x01AF, -+0x0015, -+0xD1AD, -+0xD9B6, -+0x9007, -+0x01AF, -+0x0010, -+0xD1AD, -+0xD9B6, -+0x01AF, -+0x0011, -+0x01AD, -+0x00FF, -+0xD9B6, -+0x01AF, -+0x0016, -+0x01AD, -+0x00FF, -+0xD9B6, -+0x01AF, -+0x0014, -+0xD1AD, -+0xD9B6, -+0x01AF, -+0x0012, -+0xD1AD, -+0xD9B6, -+0x01AF, -+0x0013, -+0x01AD, -+0x00FF, -+0xD9B6, -+0x01AF, -+0x0018, -+0x01AD, -+0x0080, -+0xD9B6, -+0x01AF, -+0x0015, -+0xD1AD, -+0xD9B6, -+0x9007, -+0x01AF, -+0x0010, -+0xD1AD, -+0xD9B6, -+0x01AF, -+0x0011, -+0xD1AD, -+0xD9B6, -+0x01AF, -+0x0016, -+0x01AD, -+0x00FF, -+0xD9B6, -+0x01AF, -+0x0014, -+0xD1AD, -+0xD9B6, -+0x01AF, -+0x0012, -+0xD1AD, -+0xD9B6, -+0x01AF, -+0x0013, -+0x01AD, -+0x00FF, -+0xD9B6, -+0x01AF, -+0x0018, -+0x01AD, -+0x00FF, -+0xD9B6, -+0x01AF, -+0x0015, -+0x01AD, -+0x0080, -+0xD9B6, -+0x9007, -+0x01AF, -+0x0010, -+0x01AD, -+0x0080, -+0xD9B6, -+0x01AF, -+0x0011, -+0xD1AD, -+0xD9B6, -+0x01AF, -+0x0016, -+0x01AD, -+0x00FF, -+0xD9B6, -+0x01AF, -+0x0014, -+0xD1AD, -+0xD9B6, -+0x01AF, -+0x0012, -+0xD1AD, -+0xD9B6, -+0x01AF, -+0x0013, -+0xD1AD, -+0xD9B6, -+0x01AF, -+0x0018, -+0x01AD, -+0x00FF, -+0xD9B6, -+0x01AF, -+0x0015, -+0xD1AD, -+0xD9B6, -+0x9007, -+0x01AF, -+0x0010, -+0xD1AD, -+0xD9B6, -+0x01AF, -+0x0011, -+0xD1AD, -+0xD9B6, -+0x01AF, -+0x0016, -+0x01AD, -+0x00FF, -+0xD9B6, -+0x01AF, -+0x0014, -+0xD1AD, -+0xD9B6, -+0x01AF, -+0x0012, -+0x01AD, -+0x0080, -+0xD9B6, -+0x01AF, -+0x0013, -+0xD1AD, -+0xD9B6, -+0x01AF, -+0x0018, -+0x01AD, -+0x00FF, -+0xD9B6, -+0x01AF, -+0x0015, -+0xD1AD, -+0xD9B6, -+0x9007, -+0x0C4E, -+0x1B24, -+0x33AE, -+0xAEF2, -+0x8F27, -+0x038D, -+0x0029, -+0x0C2F, -+0xDB75, -+0x33AF, -+0x0C6F, -+0x010D, -+0x0002, -+0x33AF, -+0xD3A6, -+0x03A6, -+0x000A, -+0x0C2E, -+0x1B24, -+0x33AE, -+0xAF10, -+0xD9AE, -+0x01AF, -+0x0016, -+0xD1AD, -+0xD9B6, -+0x01AF, -+0x0018, -+0x01AD, -+0x00FF, -+0xD9B6, -+0x0C2F, -+0xDB24, -+0x33AF, -+0x8F1D, -+0xD9AE, -+0x01AF, -+0x0016, -+0x01AD, -+0x00FF, -+0xD9B6, -+0x01AF, -+0x0018, -+0xD1AD, -+0xD9B6, -+0x0C2F, -+0xD324, -+0x33AF, -+0xD1AE, -+0xD3A6, -+0x7000, -+0x0C6F, -+0xD10D, -+0x33AF, -+0x0C2F, -+0xD375, -+0x33AF, -+0xD38D, -+0x8A09, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0180, -+0x7D00, -+0x0181, -+0xAAAA, -+0x0182, -+0x2802, -+0x0183, -+0x0800, -+0x0184, -+0x3060, -+0x0185, -+0x6402, -+0x0160, -+0x0C1F, -+0xD161, -+0x0162, -+0x0042, -+0x0163, -+0x3000, -+0xD164, -+0x0165, -+0x3000, -+0x0166, -+0x7828, -+0x0167, -+0x21A2, -+0xD168, -+0x0169, -+0xB7B7, -+0x6E00, -+0x197B, -+0x430D, -+0x31BA, -+0x0180, -+0x7D00, -+0x0181, -+0xAAAA, -+0x0182, -+0x2802, -+0x0183, -+0x0800, -+0x0184, -+0x3060, -+0x0185, -+0x6402, -+0x0160, -+0x0C1F, -+0xD161, -+0xD162, -+0x0163, -+0x3000, -+0xD164, -+0x0165, -+0xB000, -+0x0166, -+0x7828, -+0x0167, -+0x21A2, -+0xD168, -+0x0169, -+0x4949, -+0x6E00, -+0x197B, -+0x430D, -+0x55BA, -+0xB043, -+0x0C0D, -+0x080F, -+0x00FF, -+0x2BE9, -+0x33AE, -+0x8D47, -+0x2BCA, -+0x33DF, -+0x8CC6, -+0x01A8, -+0x0140, -+0xD9B5, -+0x01AC, -+0xA200, -+0x0180, -+0x03FF, -+0xD981, -+0xD182, -+0xD183, -+0x0184, -+0x4000, -+0x0185, -+0x2408, -+0x0800, -+0x0349, -+0x0802, -+0x034A, -+0x0803, -+0x01B4, -+0x080E, -+0x01E0, -+0x1B1C, -+0x33AE, -+0x31A4, -+0x0EED, -+0x35A0, -+0x3C43, -+0xD9B8, -+0x0816, -+0x006B, -+0x8071, -+0xD1B5, -+0x33DF, -+0x1B27, -+0xA070, -+0x863A, -+0x8644, -+0x7080, -+0x1B27, -+0xA084, -+0x1B35, -+0xA084, -+0x0801, -+0x0022, -+0x3805, -+0x0DCD, -+0x54AD, -+0xA07D, -+0x8081, -+0x5E20, -+0x3C43, -+0xD9B8, -+0x8078, -+0x6670, -+0xB084, -+0x80AF, -+0x380D, -+0x2B53, -+0x1B34, -+0xA0AE, -+0x308D, -+0xA08B, -+0x80AE, -+0x3805, -+0x0CED, -+0x54AD, -+0xA090, -+0x80A3, -+0x0DED, -+0x54AD, -+0xA094, -+0x80A3, -+0x0EED, -+0x54AD, -+0xA098, -+0x80A3, -+0x0FED, -+0x54AD, -+0xA09C, -+0x80A3, -+0x080D, -+0x0027, -+0x54AD, -+0xA0A1, -+0x80A3, -+0x5C24, -+0x31A4, -+0x5A20, -+0x3805, -+0x0818, -+0x002F, -+0x54B8, -+0xB0AB, -+0x5E20, -+0x80AE, -+0x3C43, -+0xD9B8, -+0x8088, -+0x9016, -+0x5A20, -+0x55A1, -+0xB0B6, -+0x3580, -+0x318D, -+0x2B53, -+0x8084, -+0x3C43, -+0xD9B8, -+0x700F, -+0x8081, -+0x0800, -+0x0349, -+0x0802, -+0x034A, -+0x0803, -+0x01B4, -+0x302D, -+0xA0C4, -+0x13C9, -+0x80C5, -+0x308C, -+0x80CB, -+0x3C43, -+0xD9B8, -+0xD1B5, -+0x33DF, -+0x9007, -+0x3804, -+0x5584, -+0xB0E0, -+0x548C, -+0x31A4, -+0x0801, -+0x002F, -+0x308D, -+0xA0D5, -+0x80DF, -+0x5C24, -+0x31A4, -+0x5A20, -+0x3805, -+0x54A1, -+0xB0DC, -+0x80DF, -+0x3C43, -+0xD9B8, -+0x80D2, -+0x80C6, -+0x31A4, -+0x0C01, -+0x308D, -+0xA0E5, -+0x80EF, -+0x5C24, -+0x31A4, -+0x5E20, -+0x3805, -+0x5425, -+0xB0EC, -+0x80EF, -+0x3C43, -+0xD9B8, -+0x80E2, -+0x80C6, -+0x0E0E, -+0x1B6F, -+0x33AE, -+0xA275, -+0x0180, -+0x03FF, -+0x0181, -+0xFFFF, -+0x0182, -+0x3C46, -+0xD183, -+0x0184, -+0x7020, -+0x0185, -+0x2404, -+0x0160, -+0x0C10, -+0x0161, -+0x0009, -+0x0162, -+0x00C2, -+0xD163, -+0xD164, -+0xD165, -+0x0166, -+0x792B, -+0x0167, -+0x21A2, -+0x0168, -+0x4925, -+0xD169, -+0x1B33, -+0xA127, -+0x0C21, -+0x0C42, -+0x13F2, -+0x542C, -+0xA11E, -+0x0181, -+0xAAAA, -+0x080F, -+0x3C00, -+0x0182, -+0x000A, -+0x33AF, -+0x8127, -+0x544C, -+0xA127, -+0x0181, -+0x5555, -+0x080F, -+0x3C00, -+0x0182, -+0x0005, -+0x33AF, -+0x080E, -+0x8000, -+0x1963, -+0x33AE, -+0xA131, -+0x080E, -+0x0FE0, -+0x116E, -+0x33AE, -+0x8135, -+0x080E, -+0x0FC0, -+0x116E, -+0x33AE, -+0x3184, -+0x080E, -+0x1000, -+0x116E, -+0x33AE, -+0x3185, -+0x13CC, -+0x3181, -+0x1351, -+0x502C, -+0x31AC, -+0x0C23, -+0x5465, -+0xB148, -+0x548C, -+0x31A2, -+0xB15C, -+0x0C02, -+0x815C, -+0x080E, -+0x8000, -+0x1963, -+0x33AE, -+0xA150, -+0x0803, -+0x0080, -+0x8152, -+0x0803, -+0x0040, -+0x548C, -+0x506D, -+0x31A2, -+0x0803, -+0x0100, -+0x546D, -+0xB15A, -+0x815C, -+0x0802, -+0x00FF, -+0x0C2F, -+0xDB75, -+0x33AF, -+0x0C6F, -+0x010D, -+0x0002, -+0x33AF, -+0xD3A6, -+0x03A6, -+0x000A, -+0x4102, -+0x4302, -+0x304D, -+0xD9AE, -+0x29AD, -+0x01AF, -+0x0016, -+0xD9B6, -+0x13CD, -+0x3181, -+0x1352, -+0x502C, -+0x31AC, -+0x0C23, -+0x5465, -+0xB17B, -+0x548C, -+0x31A2, -+0xB18F, -+0x0C02, -+0x818F, -+0x080E, -+0x8000, -+0x1963, -+0x33AE, -+0xA183, -+0x0803, -+0x0080, -+0x8185, -+0x0803, -+0x0040, -+0x548C, -+0x506D, -+0x31A2, -+0x0803, -+0x0100, -+0x546D, -+0xB18D, -+0x818F, -+0x0802, -+0x00FF, -+0x4102, -+0x4302, -+0x304D, -+0x29AD, -+0x01AF, -+0x0018, -+0xD9B6, -+0xD1AE, -+0xD3A6, -+0x7000, -+0x0C6F, -+0xD10D, -+0x33AF, -+0x0C2F, -+0xD375, -+0x33AF, -+0x6647, -+0x080E, -+0x7FFF, -+0x1989, -+0x33AE, -+0x402D, -+0x31A3, -+0x080E, -+0x7FFF, -+0x1986, -+0x31A2, -+0x31A4, -+0x31AC, -+0x080E, -+0x01E0, -+0x1B76, -+0x33AE, -+0xA1B2, -+0x81B5, -+0x422C, -+0x5C2D, -+0x81B0, -+0x3181, -+0x4282, -+0x0C05, -+0x0DEE, -+0x1B76, -+0x33AE, -+0x31B7, -+0xA1BE, -+0x81C3, -+0x5045, -+0x31A5, -+0x5C37, -+0x31B7, -+0x81BC, -+0x0E0E, -+0x1B76, -+0x33AE, -+0xA1CA, -+0x50A4, -+0x31A2, -+0x81CC, -+0x54A4, -+0x31A2, -+0x5022, -+0x546D, -+0xB1D0, -+0x81D6, -+0x5422, -+0xB1D3, -+0x81DB, -+0x55A3, -+0xB1DB, -+0x81D8, -+0xDB12, -+0x81DC, -+0x0312, -+0x0002, -+0x81DC, -+0xD312, -+0x080E, -+0x0038, -+0x1B77, -+0x33AE, -+0x31AC, -+0x0CEE, -+0x1B77, -+0x33AE, -+0x31A0, -+0x080E, -+0x00F0, -+0x1B78, -+0x33AE, -+0x31A1, -+0x0DEE, -+0x1B78, -+0x33AE, -+0x31A2, -+0x080E, -+0x00E0, -+0x196B, -+0x33AE, -+0x31A3, -+0x080E, -+0x03C0, -+0x196C, -+0x33AE, -+0x31A4, -+0x4024, -+0x080E, -+0x003F, -+0x196C, -+0x33AE, -+0xA1FF, -+0x8201, -+0x5824, -+0x31A4, -+0x546C, -+0xB206, -+0x5444, -+0xB206, -+0x820B, -+0x5403, -+0xB210, -+0x5481, -+0xB210, -+0x820E, -+0x0313, -+0x0002, -+0x8211, -+0xDB13, -+0x8211, -+0xD313, -+0x080E, -+0x03E0, -+0x1379, -+0x33AE, -+0x3180, -+0x0FEE, -+0x1379, -+0x33AE, -+0x3181, -+0x080E, -+0x7F00, -+0x137A, -+0x33AE, -+0x3184, -+0x080E, -+0x8000, -+0x137A, -+0x33AE, -+0x3197, -+0x080E, -+0x007F, -+0x137A, -+0x33AE, -+0x3185, -+0x080E, -+0x0080, -+0x137A, -+0x33AE, -+0x3198, -+0x080E, -+0x03E0, -+0x116D, -+0x33AE, -+0x3182, -+0x0807, -+0x0236, -+0x82AB, -+0x5440, -+0xB239, -+0x8272, -+0x332D, -+0xA241, -+0x32ED, -+0xA240, -+0x5464, -+0xB247, -+0x8272, -+0x8272, -+0x32ED, -+0xA244, -+0x8247, -+0x5483, -+0xB247, -+0x8272, -+0x5422, -+0xB24A, -+0x826F, -+0x332D, -+0xA251, -+0x330D, -+0xA257, -+0x54A3, -+0xB257, -+0x826F, -+0x330D, -+0xA254, -+0x826F, -+0x5465, -+0xB257, -+0x826F, -+0x080E, -+0x03C0, -+0x196C, -+0x33AE, -+0x5CED, -+0xA274, -+0x1BED, -+0x5C8D, -+0x31AC, -+0x1BCC, -+0x55AC, -+0xA264, -+0x8266, -+0xB26F, -+0x8266, -+0x1BEE, -+0x5C8D, -+0x31AC, -+0x1BCD, -+0x55AC, -+0xA26D, -+0x8274, -+0xB26F, -+0x8274, -+0x0314, -+0x0002, -+0x8275, -+0xDB14, -+0x8275, -+0xD314, -+0x0C2F, -+0xDB75, -+0x33AF, -+0x0C6F, -+0x010D, -+0x0002, -+0x33AF, -+0xD3A6, -+0x03A6, -+0x000A, -+0x1B51, -+0x1352, -+0x3180, -+0xD9AE, -+0x29AD, -+0x01AF, -+0x0016, -+0xD9B6, -+0x21AD, -+0x01AF, -+0x0018, -+0xD9B6, -+0xD1AE, -+0xD3A6, -+0x7000, -+0x0C6F, -+0xD10D, -+0x33AF, -+0x0C2F, -+0xD375, -+0x33AF, -+0x196B, -+0x2B5A, -+0x196D, -+0x2B5C, -+0x196C, -+0x2B5B, -+0x196E, -+0x2B5D, -+0x196F, -+0x2B60, -+0x1970, -+0x2B61, -+0x1971, -+0x2B62, -+0x1972, -+0x2B63, -+0x13CD, -+0x410C, -+0x1BCC, -+0x518D, -+0x2BF1, -+0x33DF, -+0x8979, -+0x080E, -+0x1FE0, -+0x196E, -+0x33AE, -+0x31A3, -+0x080E, -+0x1000, -+0x196E, -+0x33AE, -+0x31B9, -+0xA2B7, -+0x82BB, -+0x080D, -+0x0100, -+0x546D, -+0x31A3, -+0x332D, -+0x9007, -+0x0C2F, -+0xDB75, -+0x33AF, -+0x0C6F, -+0x010D, -+0x0002, -+0x33AF, -+0xD3A6, -+0x03A6, -+0x000A, -+0x01B3, -+0x0177, -+0xD9AE, -+0x82FB, -+0x01B3, -+0x0155, -+0x01B3, -+0x0144, -+0x01B3, -+0x01CC, -+0x01B3, -+0x01EE, -+0x83DA, -+0x01B3, -+0x01CC, -+0x01B3, -+0x0144, -+0x01B3, -+0x0155, -+0x01B3, -+0x0177, -+0x84AB, -+0x01B3, -+0x0155, -+0x01B3, -+0x0111, -+0x01B3, -+0x0100, -+0x01B3, -+0x0188, -+0x859D, -+0x01B3, -+0x0100, -+0x01B3, -+0x0111, -+0x01B3, -+0x0155, -+0x01B3, -+0x0177, -+0x01B3, -+0x0077, -+0xD1AE, -+0xD3A6, -+0x7000, -+0x0C6F, -+0xD10D, -+0x33AF, -+0x0C2F, -+0xD375, -+0x33AF, -+0x0C1F, -+0x9006, -+0x0180, -+0x7D00, -+0x0181, -+0xAAAA, -+0x0182, -+0x28C6, -+0xD183, -+0x0184, -+0x2C00, -+0x0185, -+0x6408, -+0x0800, -+0x01AD, -+0x01AD, -+0x0080, -+0x01AF, -+0x0016, -+0xD9B6, -+0x0807, -+0x0313, -+0x33FE, -+0x0C1F, -+0x0C63, -+0x864B, -+0x19AD, -+0x2B47, -+0x0180, -+0x7D00, -+0x0181, -+0xAAAA, -+0x0182, -+0x2886, -+0xD183, -+0x0184, -+0x2C00, -+0x0185, -+0x6408, -+0x0800, -+0x01AD, -+0x01AD, -+0x0080, -+0x01AF, -+0x0016, -+0xD9B6, -+0x0807, -+0x032D, -+0x33FE, -+0x0C1F, -+0x0C43, -+0x864B, -+0x0807, -+0x0330, -+0x868A, -+0x31A5, -+0x0801, -+0x0020, -+0x5023, -+0x31A1, -+0x080E, -+0x00FF, -+0x13EF, -+0x33AE, -+0x3180, -+0x2179, -+0x2348, -+0x5581, -+0x43ED, -+0x31B8, -+0x080D, -+0x00FF, -+0x542D, -+0x55AC, -+0x43ED, -+0x31B9, -+0x0800, -+0x0179, -+0x30AD, -+0x0807, -+0x034C, -+0x0C04, -+0x86B5, -+0x080E, -+0x00FF, -+0x1BEF, -+0x33AE, -+0x2B48, -+0x0800, -+0x0348, -+0x0801, -+0x0347, -+0x0807, -+0x0358, -+0x866E, -+0x1B48, -+0x080F, -+0x00FF, -+0x2BEF, -+0x33AF, -+0x0800, -+0x0348, -+0x0801, -+0x0347, -+0x0802, -+0x0179, -+0x0807, -+0x0366, -+0x868A, -+0x0807, -+0x036A, -+0x0C04, -+0x869C, -+0x0180, -+0x7D00, -+0x0181, -+0x5555, -+0x0182, -+0x14C6, -+0xD183, -+0x0184, -+0x2C00, -+0x0185, -+0x6408, -+0x0800, -+0x01AD, -+0x01AD, -+0x0080, -+0x01AF, -+0x0018, -+0xD9B6, -+0x0807, -+0x0382, -+0x33FE, -+0x0C1F, -+0x0C63, -+0x864B, -+0x19AD, -+0x2B47, -+0x0180, -+0x7D00, -+0x0181, -+0x5555, -+0x0182, -+0x1486, -+0xD183, -+0x0184, -+0x2C00, -+0x0185, -+0x6408, -+0x0800, -+0x01AD, -+0x01AD, -+0x0080, -+0x01AF, -+0x0018, -+0xD9B6, -+0x0807, -+0x039C, -+0x33FE, -+0x0C1F, -+0x0C43, -+0x864B, -+0x0807, -+0x039F, -+0x868A, -+0x31A5, -+0x0801, -+0x0020, -+0x5023, -+0x31A1, -+0x080E, -+0x00FF, -+0x13F0, -+0x33AE, -+0x3180, -+0x217A, -+0x2348, -+0x5581, -+0x43ED, -+0x31B8, -+0x080D, -+0x00FF, -+0x542D, -+0x55AC, -+0x43ED, -+0x31B9, -+0x0800, -+0x017A, -+0x30AD, -+0x0807, -+0x03BB, -+0x0C04, -+0x86B5, -+0x080E, -+0x00FF, -+0x1BF0, -+0x33AE, -+0x2B48, -+0x0800, -+0x0348, -+0x0801, -+0x0347, -+0x0807, -+0x03C7, -+0x866E, -+0x1B48, -+0x080F, -+0x00FF, -+0x2BF0, -+0x33AF, -+0x0800, -+0x0348, -+0x0801, -+0x0347, -+0x0802, -+0x017A, -+0x0807, -+0x03D5, -+0x868A, -+0x0807, -+0x03D9, -+0x0C04, -+0x869C, -+0x82CB, -+0x0180, -+0x7D00, -+0x0181, -+0xAAAA, -+0x0182, -+0x28C6, -+0xD183, -+0x0184, -+0x2C00, -+0x0185, -+0x6408, -+0x0800, -+0x01AD, -+0x01AD, -+0x0080, -+0x01AF, -+0x0010, -+0xD9B6, -+0x0807, -+0x03F2, -+0x33FE, -+0x0C1F, -+0x0C63, -+0x864B, -+0x19AD, -+0x2B47, -+0x0180, -+0x7D00, -+0x0181, -+0xAAAA, -+0x0182, -+0x2886, -+0xD183, -+0x0184, -+0x2C00, -+0x0185, -+0x6408, -+0x0800, -+0x01AD, -+0x01AD, -+0x0080, -+0x01AF, -+0x0010, -+0xD9B6, -+0x0807, -+0x040C, -+0x33FE, -+0x0C1F, -+0x0C43, -+0x864B, -+0x0807, -+0x040F, -+0x868A, -+0x31A5, -+0x0801, -+0x0020, -+0x5023, -+0x134B, -+0x3180, -+0x2173, -+0x2348, -+0x558D, -+0x43ED, -+0x31B8, -+0x0801, -+0x0020, -+0x5061, -+0x0801, -+0x00FF, -+0x55A1, -+0x55AC, -+0x43ED, -+0x31B9, -+0x0800, -+0x0173, -+0x30AD, -+0x0807, -+0x042A, -+0x0C04, -+0x86B5, -+0x1B4B, -+0x2B48, -+0x0800, -+0x0348, -+0x0801, -+0x0347, -+0x0807, -+0x0433, -+0x866E, -+0x1B48, -+0x2B4B, -+0x0800, -+0x0348, -+0x0801, -+0x0347, -+0x0802, -+0x0173, -+0x0807, -+0x043E, -+0x868A, -+0x0807, -+0x0442, -+0x0C04, -+0x869C, -+0x0180, -+0x7D00, -+0x0181, -+0x5555, -+0x0182, -+0x14C6, -+0xD183, -+0x0184, -+0x2C00, -+0x0185, -+0x6408, -+0x0800, -+0x01AD, -+0x01AD, -+0x0080, -+0x01AF, -+0x0012, -+0xD9B6, -+0x0807, -+0x045A, -+0x33FE, -+0x0C1F, -+0x0C63, -+0x864B, -+0x19AD, -+0x2B47, -+0x0180, -+0x7D00, -+0x0181, -+0x5555, -+0x0182, -+0x1486, -+0xD183, -+0x0184, -+0x2C00, -+0x0185, -+0x6408, -+0x0800, -+0x01AD, -+0x01AD, -+0x0080, -+0x01AF, -+0x0012, -+0xD9B6, -+0x0807, -+0x0474, -+0x33FE, -+0x0C1F, -+0x0C43, -+0x864B, -+0x0807, -+0x0477, -+0x868A, -+0x31A5, -+0x0801, -+0x0020, -+0x5023, -+0x134D, -+0x3180, -+0x2175, -+0x2348, -+0x558D, -+0x43ED, -+0x31B8, -+0x0801, -+0x0020, -+0x5061, -+0x0801, -+0x00FF, -+0x55A1, -+0x55AC, -+0x43ED, -+0x31B9, -+0x0800, -+0x0175, -+0x30AD, -+0x0807, -+0x0492, -+0x0C04, -+0x86B5, -+0x1B4D, -+0x2B48, -+0x0800, -+0x0348, -+0x0801, -+0x0347, -+0x0807, -+0x049B, -+0x866E, -+0x1B48, -+0x2B4D, -+0x0800, -+0x0348, -+0x0801, -+0x0347, -+0x0802, -+0x0175, -+0x0807, -+0x04A6, -+0x868A, -+0x0807, -+0x04AA, -+0x0C04, -+0x869C, -+0x82D4, -+0x0180, -+0x7D00, -+0x0181, -+0xAAAA, -+0x0182, -+0x2846, -+0xD183, -+0x0184, -+0x2C00, -+0x0185, -+0x6408, -+0x0800, -+0x01AD, -+0x01AD, -+0x0080, -+0x01AF, -+0x0016, -+0xD9B6, -+0x0807, -+0x04C3, -+0x33FE, -+0x0C1F, -+0x0C63, -+0x864B, -+0x19AD, -+0x2B47, -+0x0180, -+0x7D00, -+0x0181, -+0xAAAA, -+0x0182, -+0x2806, -+0xD183, -+0x0184, -+0x2C00, -+0x0185, -+0x6408, -+0x0800, -+0x01AD, -+0x01AD, -+0x0080, -+0x01AF, -+0x0016, -+0xD9B6, -+0x0807, -+0x04DD, -+0x33FE, -+0x0C1F, -+0x0C43, -+0x864B, -+0x0807, -+0x04E0, -+0x868A, -+0x31A5, -+0x0801, -+0x0020, -+0x5023, -+0x080E, -+0xFF00, -+0x13EF, -+0x33AE, -+0x3180, -+0x2179, -+0x2348, -+0x558D, -+0x43ED, -+0x31B8, -+0x080D, -+0x00FF, -+0x542D, -+0x55AC, -+0x43ED, -+0x31B9, -+0x0800, -+0x0179, -+0x30AD, -+0x0807, -+0x04FB, -+0x0C24, -+0x86B5, -+0x080E, -+0xFF00, -+0x1BEF, -+0x33AE, -+0x2B48, -+0x0800, -+0x0348, -+0x0801, -+0x0347, -+0x0807, -+0x0507, -+0x866E, -+0x1B48, -+0x080F, -+0xFF00, -+0x2BEF, -+0x33AF, -+0x0800, -+0x0348, -+0x0801, -+0x0347, -+0x0802, -+0x0179, -+0x0807, -+0x0515, -+0x868A, -+0x0807, -+0x0519, -+0x0C24, -+0x869C, -+0x0180, -+0x7D00, -+0x0181, -+0x5555, -+0x0182, -+0x1446, -+0xD183, -+0x0184, -+0x2C00, -+0x0185, -+0x6408, -+0x0800, -+0x01AD, -+0x01AD, -+0x0080, -+0x01AF, -+0x0018, -+0xD9B6, -+0x0807, -+0x0531, -+0x33FE, -+0x0C1F, -+0x0C63, -+0x864B, -+0x19AD, -+0x2B47, -+0x0180, -+0x7D00, -+0x0181, -+0x5555, -+0x0182, -+0x1406, -+0xD183, -+0x0184, -+0x2C00, -+0x0185, -+0x6408, -+0x0800, -+0x01AD, -+0x01AD, -+0x0080, -+0x01AF, -+0x0018, -+0xD9B6, -+0x0807, -+0x054B, -+0x33FE, -+0x0C1F, -+0x0C43, -+0x864B, -+0x0807, -+0x054E, -+0x868A, -+0x31A5, -+0x0801, -+0x0020, -+0x5023, -+0x31A1, -+0x080E, -+0xFF00, -+0x13F0, -+0x33AE, -+0x3180, -+0x217A, -+0x2348, -+0x5581, -+0x43ED, -+0x31B8, -+0x080D, -+0x00FF, -+0x542D, -+0x55AC, -+0x43ED, -+0x31B9, -+0x0800, -+0x017A, -+0x30AD, -+0x0807, -+0x056A, -+0x0C24, -+0x86B5, -+0x080E, -+0xFF00, -+0x1BF0, -+0x33AE, -+0x2B48, -+0x0800, -+0x0348, -+0x0801, -+0x0347, -+0x0807, -+0x0576, -+0x866E, -+0x1B48, -+0x080F, -+0xFF00, -+0x2BF0, -+0x33AF, -+0x0800, -+0x0348, -+0x0801, -+0x0347, -+0x0802, -+0x017A, -+0x0807, -+0x0584, -+0x868A, -+0x0807, -+0x0588, -+0x0C24, -+0x869C, -+0x080E, -+0xFF00, -+0x1BEF, -+0x080E, -+0x00FF, -+0x13EF, -+0x33AE, -+0x518D, -+0x422D, -+0x2B51, -+0x080E, -+0xFF00, -+0x1BF0, -+0x080E, -+0x00FF, -+0x13F0, -+0x33AE, -+0x518D, -+0x422D, -+0x2B52, -+0x82DD, -+0x0180, -+0x7D00, -+0x0181, -+0xAAAA, -+0x0182, -+0x2846, -+0xD183, -+0x0184, -+0x2C00, -+0x0185, -+0x6408, -+0x0800, -+0x01AD, -+0x01AD, -+0x0080, -+0x01AF, -+0x0011, -+0xD9B6, -+0x0807, -+0x05B5, -+0x33FE, -+0x0C1F, -+0x0C63, -+0x864B, -+0x19AD, -+0x2B47, -+0x0180, -+0x7D00, -+0x0181, -+0xAAAA, -+0x0182, -+0x2806, -+0xD183, -+0x0184, -+0x2C00, -+0x0185, -+0x6408, -+0x0800, -+0x01AD, -+0x01AD, -+0x0080, -+0x01AF, -+0x0011, -+0xD9B6, -+0x0807, -+0x05CF, -+0x33FE, -+0x0C1F, -+0x0C43, -+0x864B, -+0x0807, -+0x05D2, -+0x868A, -+0x31A5, -+0x0801, -+0x0020, -+0x5023, -+0x134C, -+0x3180, -+0x2174, -+0x2348, -+0x558D, -+0x43ED, -+0x31B8, -+0x0801, -+0x0020, -+0x5061, -+0x0801, -+0x00FF, -+0x55A1, -+0x55AC, -+0x43ED, -+0x31B9, -+0x0800, -+0x0174, -+0x30AD, -+0x0807, -+0x05ED, -+0x0C24, -+0x86B5, -+0x1B4C, -+0x2B48, -+0x0800, -+0x0348, -+0x0801, -+0x0347, -+0x0807, -+0x05F6, -+0x866E, -+0x1B48, -+0x2B4C, -+0x0800, -+0x0348, -+0x0801, -+0x0347, -+0x0802, -+0x0174, -+0x0807, -+0x0601, -+0x868A, -+0x0807, -+0x0605, -+0x0C24, -+0x869C, -+0x0180, -+0x7D00, -+0x0181, -+0x5555, -+0x0182, -+0x1446, -+0xD183, -+0x0184, -+0x2C00, -+0x0185, -+0x6408, -+0x0800, -+0x01AD, -+0x01AD, -+0x0080, -+0x01AF, -+0x0013, -+0xD9B6, -+0x0807, -+0x061D, -+0x33FE, -+0x0C1F, -+0x0C63, -+0x864B, -+0x19AD, -+0x2B47, -+0x0180, -+0x7D00, -+0x0181, -+0x5555, -+0x0182, -+0x1406, -+0xD183, -+0x0184, -+0x2C00, -+0x0185, -+0x6408, -+0x0800, -+0x01AD, -+0x01AD, -+0x0080, -+0x01AF, -+0x0013, -+0xD9B6, -+0x0807, -+0x0637, -+0x33FE, -+0x0C1F, -+0x0C43, -+0x864B, -+0x0807, -+0x063A, -+0x868A, -+0x31A5, -+0x0801, -+0x0020, -+0x5023, -+0x134E, -+0x3180, -+0x2176, -+0x2348, -+0x558D, -+0x43ED, -+0x31B8, -+0x0801, -+0x0020, -+0x5061, -+0x0801, -+0x00FF, -+0x55A1, -+0x55AC, -+0x43ED, -+0x31B9, -+0x0800, -+0x0176, -+0x30AD, -+0x0807, -+0x0655, -+0x0C24, -+0x86B5, -+0x1B4E, -+0x2B48, -+0x0800, -+0x0348, -+0x0801, -+0x0347, -+0x0807, -+0x065E, -+0x866E, -+0x1B48, -+0x2B4E, -+0x0800, -+0x0348, -+0x0801, -+0x0347, -+0x0802, -+0x0176, -+0x0807, -+0x0669, -+0x868A, -+0x0807, -+0x066D, -+0x0C24, -+0x869C, -+0x82E6, -+0x19AD, -+0x31A4, -+0x3825, -+0x5085, -+0x31A5, -+0x4225, -+0x3C01, -+0x338D, -+0x55A5, -+0xB67B, -+0x330D, -+0xA67E, -+0x8689, -+0xA682, -+0x380D, -+0x8689, -+0x5E20, -+0xB689, -+0x3580, -+0x8689, -+0x332D, -+0xA685, -+0x8689, -+0x5A20, -+0x31A2, -+0x430D, -+0xA680, -+0x9007, -+0x080E, -+0x1FE0, -+0x196E, -+0x33AE, -+0x31A3, -+0x080E, -+0x1000, -+0x196E, -+0x33AE, -+0x31A4, -+0xA696, -+0x869A, -+0x080D, -+0x0100, -+0x546D, -+0x31A3, -+0x308D, -+0x9007, -+0xA6A0, -+0x308D, -+0xA6AA, -+0x86A3, -+0x308D, -+0xA6A3, -+0x86AA, -+0x3805, -+0x5065, -+0x31A4, -+0x430D, -+0xA6B1, -+0x308D, -+0x86AE, -+0x3805, -+0x5465, -+0xB6AE, -+0x86B1, -+0x3C02, -+0x35A1, -+0x86B2, -+0x384D, -+0x29AD, -+0xD9B6, -+0x9007, -+0xA6B9, -+0x308D, -+0xA6C3, -+0x86BC, -+0x308D, -+0xA6BC, -+0x86C3, -+0x3805, -+0x5065, -+0x31A4, -+0x430D, -+0xA6C9, -+0x308D, -+0x86C7, -+0x3805, -+0x5465, -+0xB6C7, -+0x86C9, -+0x31BC, -+0x86CA, -+0x30BC, -+0x9007, -+0x0180, -+0x00FF, -+0x0181, -+0xAAAA, -+0x0182, -+0x2806, -+0x0183, -+0x0800, -+0x0184, -+0x7060, -+0x0185, -+0x2402, -+0x0160, -+0x0C07, -+0xD161, -+0x0162, -+0x00C6, -+0x0163, -+0x1000, -+0xD164, -+0x0165, -+0x3000, -+0x0166, -+0x7828, -+0x0167, -+0x21A2, -+0xD168, -+0x1B38, -+0xA712, -+0x1BCC, -+0x31A1, -+0x1B51, -+0x502D, -+0x31A1, -+0x0807, -+0x06F0, -+0x8DF4, -+0xA6F3, -+0x5061, -+0x86F4, -+0x5461, -+0xB6F6, -+0x86FE, -+0x31A1, -+0x430D, -+0xA6FB, -+0x302D, -+0x86FF, -+0x080D, -+0x00FF, -+0x86FF, -+0x0C0D, -+0x080F, -+0x00FF, -+0x2969, -+0x33AF, -+0x1BCD, -+0x31A1, -+0x1B52, -+0x502D, -+0x31A1, -+0x080F, -+0xFF00, -+0x2969, -+0x33AF, -+0x6C00, -+0x080E, -+0xFF00, -+0x197B, -+0x33AE, -+0x31B8, -+0x0180, -+0x00FF, -+0x0162, -+0x0084, -+0x0165, -+0xB000, -+0x1B38, -+0xA73B, -+0x1B51, -+0x31A1, -+0x13CC, -+0x0807, -+0x0720, -+0x8DF4, -+0xA724, -+0x5061, -+0x558D, -+0x8726, -+0x506C, -+0x55A1, -+0x31A1, -+0xB729, -+0x8730, -+0x430D, -+0xA72D, -+0x302D, -+0x8731, -+0x080D, -+0x00FF, -+0x8731, -+0x0C0D, -+0x080F, -+0x00FF, -+0x2969, -+0x33AF, -+0x6C00, -+0x080E, -+0xFF00, -+0x197B, -+0x33AE, -+0x31B9, -+0x0180, -+0x00FF, -+0x0181, -+0x5555, -+0x0182, -+0x1406, -+0x0162, -+0x00C6, -+0x0163, -+0x2000, -+0x0165, -+0x3000, -+0x080F, -+0x03FF, -+0xD960, -+0x33AF, -+0x1B38, -+0xA759, -+0x1352, -+0x1B51, -+0x55B8, -+0x518D, -+0x410D, -+0x2969, -+0x6C00, -+0x080E, -+0x00FF, -+0x197B, -+0x33AE, -+0x31BA, -+0x0180, -+0x00FF, -+0x0162, -+0x0084, -+0x0165, -+0xB000, -+0x080F, -+0x03FF, -+0xD960, -+0x33AF, -+0x1B38, -+0xA793, -+0x1352, -+0x1B51, -+0x55B9, -+0x51AC, -+0x410D, -+0x2969, -+0x6C00, -+0x080E, -+0x00FF, -+0x197B, -+0x33AE, -+0x31BB, -+0x0C2F, -+0xDB75, -+0x33AF, -+0x0C6F, -+0x010D, -+0x0002, -+0x33AF, -+0xD3A6, -+0x03A6, -+0x000A, -+0x5738, -+0x424D, -+0x532D, -+0xD9AE, -+0x29AD, -+0x01AF, -+0x0016, -+0xD9B6, -+0x577A, -+0x424D, -+0x536D, -+0x29AD, -+0x01AF, -+0x0018, -+0xD9B6, -+0xD1AE, -+0xD3A6, -+0x7000, -+0x0C6F, -+0xD10D, -+0x33AF, -+0x0C2F, -+0xD375, -+0x33AF, -+0x0180, -+0x01FF, -+0x0181, -+0xFFFF, -+0x0182, -+0x3C86, -+0xD183, -+0x0160, -+0x0C10, -+0x0161, -+0x0009, -+0x0162, -+0x00C2, -+0xD163, -+0xD165, -+0x0166, -+0x792B, -+0x0168, -+0x4925, -+0x1B38, -+0xA82D, -+0x0807, -+0x07AD, -+0x33FE, -+0x0C1F, -+0x89C5, -+0x1959, -+0x1959, -+0x31B6, -+0x0807, -+0x07B3, -+0x8931, -+0x081C, -+0x0349, -+0x0EA1, -+0x0C17, -+0x3B85, -+0x080D, -+0x002F, -+0x5C2D, -+0x54AD, -+0xB7BE, -+0x87F9, -+0x302D, -+0xA7C1, -+0x87F9, -+0x3B85, -+0x0CED, -+0x54AD, -+0xA7C6, -+0x87DB, -+0x0DED, -+0x54AD, -+0xA7CA, -+0x87DB, -+0x0EED, -+0x54AD, -+0xA7CE, -+0x87DB, -+0x0FED, -+0x54AD, -+0xA7D2, -+0x87DB, -+0x080D, -+0x0027, -+0x54AD, -+0xA7D7, -+0x87DB, -+0x5C21, -+0x31A1, -+0x5837, -+0x31B7, -+0x5A3C, -+0x1B4A, -+0x29B4, -+0xD9B8, -+0x1959, -+0x1959, -+0x31A2, -+0x5444, -+0xB7E5, -+0x87F9, -+0x5462, -+0xB7E8, -+0x87F9, -+0x6620, -+0x080E, -+0x7FFF, -+0x1988, -+0x33AE, -+0x31A2, -+0x4022, -+0x080E, -+0x7FFF, -+0x1986, -+0x33AE, -+0x31A5, -+0x4025, -+0x426D, -+0x55A5, -+0x55A2, -+0xB7B7, -+0x32E0, -+0x3B81, -+0x1B47, -+0x55A1, -+0xA7FF, -+0x8807, -+0xB802, -+0x5A3C, -+0x8803, -+0x5E3C, -+0x1B4A, -+0x29B4, -+0xD9B8, -+0x87FA, -+0x0C17, -+0x1959, -+0x1959, -+0x31A2, -+0x5444, -+0xB80E, -+0x8810, -+0x5462, -+0xB813, -+0x0807, -+0x0813, -+0x8917, -+0x1959, -+0x1959, -+0x31A2, -+0x5444, -+0xB81F, -+0x5E3C, -+0x1B4A, -+0x29B4, -+0xD9B8, -+0x5E3C, -+0x5857, -+0x8827, -+0x5462, -+0xB82D, -+0x5A3C, -+0x1B4A, -+0x29B4, -+0xD9B8, -+0x5A3C, -+0x5840, -+0x1B4A, -+0x29B4, -+0xD9B8, -+0x0807, -+0x082D, -+0x8917, -+0x0180, -+0x01FF, -+0x0182, -+0x3CC6, -+0x1B38, -+0xA8BF, -+0x0807, -+0x0838, -+0x33FE, -+0x0C1F, -+0x89C5, -+0x0C2F, -+0xDB75, -+0x33AF, -+0x0C6F, -+0x010D, -+0x0002, -+0x33AF, -+0xD3A6, -+0x03A6, -+0x000A, -+0x5738, -+0x424D, -+0x55B8, -+0xD9AE, -+0x29AD, -+0x01AF, -+0x0016, -+0xD9B6, -+0x577A, -+0x424D, -+0x55BA, -+0x29AD, -+0x01AF, -+0x0018, -+0xD9B6, -+0xD1AE, -+0xD3A6, -+0x7000, -+0x0C6F, -+0xD10D, -+0x33AF, -+0x0C2F, -+0xD375, -+0x33AF, -+0x081C, -+0x0349, -+0x0EA1, -+0x3B85, -+0x0C0D, -+0x582D, -+0x55A5, -+0xB863, -+0x889C, -+0x302D, -+0xA866, -+0x889C, -+0x3B85, -+0x0D0D, -+0x54AD, -+0xA86B, -+0x8881, -+0x0E0D, -+0x54AD, -+0xA86F, -+0x8881, -+0x0F0D, -+0x54AD, -+0xA873, -+0x8881, -+0x080D, -+0x0020, -+0x54AD, -+0xA878, -+0x8881, -+0x080D, -+0x0028, -+0x54AD, -+0xA87D, -+0x8881, -+0x5C21, -+0x31A1, -+0x5837, -+0x31B7, -+0x5E3C, -+0x1B4A, -+0x29B4, -+0xD9B8, -+0x1959, -+0x1959, -+0x31A2, -+0x5444, -+0xB88B, -+0x889C, -+0x5462, -+0xB88E, -+0x889C, -+0x6620, -+0x080E, -+0x7FFF, -+0x1988, -+0x33AE, -+0x31A2, -+0x4022, -+0x080E, -+0x7FFF, -+0x1986, -+0x33AE, -+0x426D, -+0x544D, -+0xB85D, -+0x32ED, -+0x300D, -+0x080F, -+0xFF00, -+0x2BEA, -+0x33AF, -+0x32ED, -+0x080F, -+0x00FF, -+0x2BEA, -+0x33AF, -+0x56E0, -+0xB8B5, -+0x5417, -+0x5C2D, -+0x422D, -+0x31A0, -+0x5C6D, -+0xB8B3, -+0x0C6C, -+0x540C, -+0x31AC, -+0x88B9, -+0x0C0C, -+0x88BE, -+0x582D, -+0x422D, -+0x586D, -+0x31AC, -+0x5D2D, -+0xB8BC, -+0x88BE, -+0x0D2C, -+0x88BE, -+0x8998, -+0x1B38, -+0xA8D3, -+0x3B8D, -+0x331C, -+0x31B8, -+0x2B7B, -+0x0807, -+0x08C9, -+0x32CD, -+0x8931, -+0x1959, -+0x1959, -+0x31A2, -+0x5482, -+0xB8D0, -+0x5462, -+0xB8D3, -+0x0807, -+0x08D3, -+0x8917, -+0x0807, -+0x08D6, -+0x8DF4, -+0x31A2, -+0xA8E0, -+0x573C, -+0xB8DC, -+0x462D, -+0x88DD, -+0x422D, -+0x532D, -+0x546D, -+0x88E7, -+0x573C, -+0xB8E4, -+0x462D, -+0x88E5, -+0x422D, -+0x532D, -+0x506D, -+0x31A1, -+0xB8EB, -+0x0C0D, -+0x88F1, -+0x430D, -+0xA8EF, -+0x302D, -+0x88F1, -+0x080D, -+0x00FF, -+0x080F, -+0x00FF, -+0x2BE8, -+0x33AF, -+0x304D, -+0xA8FF, -+0x577A, -+0xB8FB, -+0x462D, -+0x88FC, -+0x422D, -+0x536D, -+0x546D, -+0x8906, -+0x577A, -+0xB903, -+0x462D, -+0x8904, -+0x422D, -+0x536D, -+0x506D, -+0x31A1, -+0xB90A, -+0x0C0D, -+0x8910, -+0x430D, -+0xA90E, -+0x302D, -+0x8910, -+0x080D, -+0x00FF, -+0x080F, -+0xFF00, -+0x2BE8, -+0x33AF, -+0x0C1F, -+0x33FE, -+0x88EC, -+0x32CD, -+0x2959, -+0x080F, -+0x0020, -+0xD906, -+0x33AF, -+0x0E0F, -+0xD106, -+0x33AF, -+0x0C8E, -+0x1919, -+0x33AE, -+0xA920, -+0x0E0F, -+0xD906, -+0x33AF, -+0x0C8E, -+0x1919, -+0x33AE, -+0xA92C, -+0x8927, -+0x080F, -+0x0020, -+0xD106, -+0x33AF, -+0x9007, -+0x31A0, -+0x0803, -+0x1000, -+0x546D, -+0xB938, -+0x0C03, -+0x8939, -+0x31A3, -+0x0804, -+0x1000, -+0x5080, -+0x31A0, -+0x0804, -+0x4000, -+0x55A4, -+0xB944, -+0x0804, -+0x4000, -+0x8945, -+0x3004, -+0x9007, -+0x1B53, -+0x31A5, -+0x3181, -+0x302D, -+0xA94C, -+0x8965, -+0x0CED, -+0x54AD, -+0xA950, -+0x8963, -+0x0DED, -+0x54AD, -+0xA954, -+0x8963, -+0x0EED, -+0x54AD, -+0xA958, -+0x8963, -+0x0FED, -+0x54AD, -+0xA95C, -+0x8963, -+0x080D, -+0x0027, -+0x54AD, -+0xA961, -+0x8963, -+0x5C21, -+0x31A1, -+0x5825, -+0x8949, -+0x1B49, -+0x31A0, -+0x54AD, -+0xB981, -+0x5405, -+0x31A1, -+0x081C, -+0x0349, -+0x3B85, -+0x080D, -+0x002F, -+0x5C2D, -+0x54AD, -+0xB974, -+0x897E, -+0x302D, -+0xA977, -+0x897E, -+0x5C21, -+0x31A1, -+0x5A3C, -+0x1B4A, -+0x29B4, -+0xD9B8, -+0x896D, -+0x0C1F, -+0x33FE, -+0x8721, -+0x54A0, -+0x31A1, -+0x081C, -+0x0349, -+0x3B85, -+0x0C0D, -+0x582D, -+0x55A5, -+0xB98B, -+0x8995, -+0x302D, -+0xA98E, -+0x8995, -+0x5C21, -+0x31A1, -+0x5E3C, -+0x1B4A, -+0x29B4, -+0xD9B8, -+0x8985, -+0x0C1F, -+0x33FE, -+0x8721, -+0x1B53, -+0x31A5, -+0x3181, -+0x302D, -+0xA99E, -+0x89B7, -+0x0CED, -+0x54AD, -+0xA9A2, -+0x89B5, -+0x0DED, -+0x54AD, -+0xA9A6, -+0x89B5, -+0x0EED, -+0x54AD, -+0xA9AA, -+0x89B5, -+0x0FED, -+0x54AD, -+0xA9AE, -+0x89B5, -+0x080D, -+0x0027, -+0x54AD, -+0xA9B3, -+0x89B5, -+0x5C21, -+0x31A1, -+0x5825, -+0x899B, -+0x1B49, -+0x31A0, -+0x54AD, -+0xB9D1, -+0x5405, -+0x31A1, -+0x081C, -+0x0349, -+0x3B85, -+0x080D, -+0x002F, -+0x5C2D, -+0x54AD, -+0xB9C6, -+0x89D0, -+0x302D, -+0xA9C9, -+0x89D0, -+0x5C21, -+0x31A1, -+0x5A3C, -+0x1B4A, -+0x29B4, -+0xD9B8, -+0x89BF, -+0x88BF, -+0x54A0, -+0x31A1, -+0x081C, -+0x0349, -+0x3B85, -+0x0C0D, -+0x582D, -+0x55A5, -+0xB9DB, -+0x89E5, -+0x302D, -+0xA9DE, -+0x89E5, -+0x5C21, -+0x31A1, -+0x5E3C, -+0x1B4A, -+0x29B4, -+0xD9B8, -+0x89D5, -+0x88BF, -+0x0180, -+0x00FF, -+0x0181, -+0xAAAA, -+0x0182, -+0x2806, -+0x0183, -+0x0800, -+0x0184, -+0x7060, -+0x0185, -+0x2402, -+0x300D, -+0x080F, -+0x03E0, -+0x2982, -+0x33AF, -+0x0FEF, -+0x0182, -+0x0006, -+0x33AF, -+0x080F, -+0x0800, -+0xD183, -+0x33AF, -+0x0160, -+0x0C07, -+0xD161, -+0x0162, -+0x00C6, -+0x0163, -+0x1000, -+0xD164, -+0x0165, -+0x3000, -+0x0166, -+0x7828, -+0x0167, -+0x21A2, -+0xD168, -+0x302D, -+0x080F, -+0xF000, -+0x2965, -+0x33AF, -+0x304D, -+0x080F, -+0x03FF, -+0x2960, -+0x33AF, -+0x306D, -+0xAA4B, -+0x300D, -+0x5CCD, -+0xAA1E, -+0x8A21, -+0x300D, -+0x5C4D, -+0xAA33, -+0x1B51, -+0x13CC, -+0x518D, -+0x31B7, -+0x430D, -+0xAA2B, -+0x32ED, -+0xBA2D, -+0x0C17, -+0x8A2D, -+0x0817, -+0x00FF, -+0x32ED, -+0x080F, -+0x00FF, -+0x2969, -+0x33AF, -+0x8A50, -+0x300D, -+0x5C8D, -+0xAA37, -+0x8A39, -+0x300D, -+0xAA50, -+0x1B51, -+0x13CC, -+0x558D, -+0x31B7, -+0xBA40, -+0x0C17, -+0x8A45, -+0x430D, -+0xAA43, -+0x8A45, -+0x0817, -+0x00FF, -+0x32ED, -+0x080F, -+0x00FF, -+0x2969, -+0x33AF, -+0x8A50, -+0x308D, -+0x080F, -+0x00FF, -+0x2969, -+0x33AF, -+0x6C00, -+0x080E, -+0xFF00, -+0x197B, -+0x33AE, -+0x0C1F, -+0x9007, -+0x0180, -+0x00FF, -+0x0181, -+0x5555, -+0x0182, -+0x1406, -+0x0183, -+0x0800, -+0x0184, -+0x7060, -+0x0185, -+0x2402, -+0x300D, -+0x080F, -+0x03E0, -+0x2982, -+0x33AF, -+0x0FEF, -+0x0182, -+0x0006, -+0x33AF, -+0x080F, -+0x0800, -+0xD183, -+0x33AF, -+0x0160, -+0x0C07, -+0xD161, -+0x0162, -+0x00C6, -+0x0163, -+0x2000, -+0xD164, -+0x0165, -+0x3000, -+0x0166, -+0x7828, -+0x0167, -+0x21A2, -+0xD168, -+0x302D, -+0x080F, -+0xF000, -+0x2965, -+0x33AF, -+0x304D, -+0x080F, -+0x03FF, -+0x2960, -+0x33AF, -+0x306D, -+0xAABC, -+0x300D, -+0x5CCD, -+0xAA8F, -+0x8A92, -+0x300D, -+0x5C4D, -+0xAAA4, -+0x1B52, -+0x13CD, -+0x518D, -+0x31B7, -+0x430D, -+0xAA9C, -+0x32ED, -+0xBA9E, -+0x0C17, -+0x8A9E, -+0x0817, -+0x00FF, -+0x32ED, -+0x080F, -+0xFF00, -+0x2969, -+0x33AF, -+0x8AC1, -+0x300D, -+0x5C8D, -+0xAAA8, -+0x8AAA, -+0x300D, -+0xAAC1, -+0x1B52, -+0x13CD, -+0x558D, -+0x31B7, -+0xBAB1, -+0x0C17, -+0x8AB6, -+0x430D, -+0xAAB4, -+0x8AB6, -+0x0817, -+0x00FF, -+0x32ED, -+0x080F, -+0xFF00, -+0x2969, -+0x33AF, -+0x8AC1, -+0x308D, -+0x080F, -+0xFF00, -+0x2969, -+0x33AF, -+0x6C00, -+0x080E, -+0x00FF, -+0x197B, -+0x33AE, -+0x0C1F, -+0x9007, -+0x0800, -+0x00F5, -+0x5418, -+0xBACF, -+0x5419, -+0xBACF, -+0x8AD5, -+0x080F, -+0x1C00, -+0x03F6, -+0x0003, -+0x33AF, -+0x8AE3, -+0x541A, -+0xBADE, -+0x541B, -+0xBADE, -+0x080F, -+0x1C00, -+0xD3F6, -+0x33AF, -+0x8AE3, -+0x080F, -+0x1C00, -+0x03F6, -+0x0005, -+0x33AF, -+0x0800, -+0x00F5, -+0x5418, -+0xBAEA, -+0x541A, -+0xBAEA, -+0x8AF3, -+0x5419, -+0xBAF3, -+0x541B, -+0xBAF3, -+0x080F, -+0x6000, -+0xDBF6, -+0x33AF, -+0x8B0F, -+0x5419, -+0xBAF8, -+0x541B, -+0xBAF8, -+0x8B02, -+0x5418, -+0xBB02, -+0x541A, -+0xBB02, -+0x080F, -+0x6000, -+0x03F6, -+0x0002, -+0x33AF, -+0x8B0F, -+0x571A, -+0xBB06, -+0x3302, -+0x8B07, -+0x3342, -+0x573B, -+0xBB0B, -+0x3323, -+0x8B0C, -+0x3363, -+0x5443, -+0xBAFC, -+0x8AEE, -+0x0C1F, -+0x9007, -+0x080E, -+0x6000, -+0x1BF6, -+0x33AE, -+0x5C2D, -+0xAB1C, -+0x1352, -+0x5379, -+0x422D, -+0x558D, -+0x8B27, -+0x080E, -+0x6000, -+0x1BF6, -+0x33AE, -+0x5C4D, -+0xAB27, -+0x1351, -+0x5358, -+0x422D, -+0x558D, -+0x8B27, -+0xBB2C, -+0x410D, -+0x430D, -+0x31B7, -+0x8B32, -+0x31B7, -+0x430D, -+0xAB30, -+0x8B32, -+0x0817, -+0x00FF, -+0x0C1F, -+0x9007, -+0x080E, -+0x00FF, -+0x196B, -+0x33AE, -+0x42AD, -+0x0CEF, -+0x290B, -+0x33AF, -+0x080E, -+0x03E0, -+0x196D, -+0x33AE, -+0x080F, -+0xF800, -+0x290B, -+0x33AF, -+0x080E, -+0x1C00, -+0x196D, -+0x33AE, -+0x0CEF, -+0x290C, -+0x33AF, -+0x080E, -+0x03C0, -+0x196C, -+0x33AE, -+0x31A0, -+0x080F, -+0x0078, -+0x290B, -+0x33AF, -+0x080E, -+0x003F, -+0x196C, -+0x33AE, -+0xAB5A, -+0x8B5C, -+0x5820, -+0x31A0, -+0x300D, -+0x080F, -+0x0780, -+0x290B, -+0x33AF, -+0x32ED, -+0x080F, -+0x07F8, -+0x290C, -+0x33AF, -+0x080E, -+0x0FFF, -+0x196F, -+0x33AE, -+0x42AD, -+0x080F, -+0x007F, -+0x291A, -+0x33AF, -+0x080E, -+0x0FFF, -+0x1970, -+0x33AE, -+0x42AD, -+0x080F, -+0x3F80, -+0x291A, -+0x33AF, -+0x080E, -+0x0FFF, -+0x1971, -+0x33AE, -+0x42AD, -+0x080F, -+0x007F, -+0x291B, -+0x33AF, -+0x080E, -+0x0FFF, -+0x1972, -+0x33AE, -+0x42AD, -+0x080F, -+0x3F80, -+0x291B, -+0x33AF, -+0x080F, -+0x0800, -+0xD90C, -+0x33AF, -+0x0C4F, -+0xD90D, -+0x33AF, -+0x0306, -+0x000C, -+0x0C2E, -+0x1919, -+0x33AE, -+0xAB98, -+0x8B93, -+0x0306, -+0x0008, -+0x080F, -+0x0800, -+0xD10C, -+0x33AF, -+0x0C4F, -+0xD10D, -+0x33AF, -+0x0C1F, -+0x9007, -+0x080E, -+0x0020, -+0x1B6F, -+0x33AE, -+0xABF4, -+0x8BF7, -+0x1B53, -+0x31A1, -+0x1B49, -+0x31B7, -+0x0802, -+0x0349, -+0x0C25, -+0x0807, -+0x0BB3, -+0x8C0F, -+0x0180, -+0x003F, -+0x0181, -+0xAAAA, -+0x0182, -+0x2802, -+0x0183, -+0x0800, -+0x0184, -+0x7060, -+0x0185, -+0x2402, -+0x0807, -+0x0BC4, -+0x33FE, -+0x0C1F, -+0x89C5, -+0x0160, -+0x0C07, -+0xD161, -+0x0162, -+0x0042, -+0x0163, -+0x3000, -+0xD164, -+0x0165, -+0x3000, -+0x0166, -+0x7828, -+0x0167, -+0x21A2, -+0xD168, -+0x330D, -+0x410D, -+0x530D, -+0x2969, -+0x6E00, -+0x197B, -+0x430D, -+0x31BA, -+0xD162, -+0x0165, -+0xB000, -+0x332D, -+0x410D, -+0x532D, -+0x2969, -+0x6E00, -+0x197B, -+0x430D, -+0x31BB, -+0x577A, -+0xBBE9, -+0x0C0D, -+0x080F, -+0x00FF, -+0x2BE9, -+0x33AE, -+0x32E1, -+0x0C05, -+0x0802, -+0x0349, -+0x0807, -+0x0BF4, -+0x8C0F, -+0x33FE, -+0x0C1F, -+0x87EA, -+0x1BF2, -+0x5C4D, -+0xABFD, -+0x1B52, -+0x13CD, -+0x8BFF, -+0x1B51, -+0x13CC, -+0x31A1, -+0x518D, -+0x31A0, -+0x430D, -+0xAC06, -+0x300D, -+0x8C08, -+0x080D, -+0x00FF, -+0x31B8, -+0x302D, -+0x558D, -+0xBC0D, -+0x0C0D, -+0x31B9, -+0x8BA9, -+0x1B49, -+0x31A0, -+0x30AD, -+0xAC18, -+0x5401, -+0xAC16, -+0x8C24, -+0xBC1D, -+0x8C24, -+0x5420, -+0xAC1B, -+0x8C24, -+0xBC1F, -+0x8C24, -+0x5A22, -+0x8C20, -+0x5E22, -+0x1B4A, -+0x29B4, -+0xD9B8, -+0x8C0F, -+0x9007, -+0x080F, -+0xFF00, -+0xD3E9, -+0x33AF, -+0x080E, -+0x00FF, -+0x13E8, -+0x33AE, -+0x0D4D, -+0x518D, -+0x31A2, -+0x080E, -+0xFF00, -+0x13E8, -+0x33AE, -+0x0D4D, -+0x518D, -+0x31A5, -+0x0807, -+0x0C3A, -+0x8DF4, -+0xAC40, -+0x5062, -+0x31A2, -+0x5065, -+0x31A5, -+0x8C48, -+0x5462, -+0x31A2, -+0xBC44, -+0x0C02, -+0x5465, -+0x31A5, -+0xBC48, -+0x0C05, -+0x304D, -+0x430D, -+0xAC4C, -+0x8C4E, -+0x0802, -+0x00FF, -+0x30AD, -+0x430D, -+0xAC52, -+0x8C54, -+0x0805, -+0x00FF, -+0x0807, -+0x0C57, -+0x8CCB, -+0x0800, -+0x0349, -+0x0802, -+0x034A, -+0x0803, -+0x01B4, -+0x3818, -+0x0C01, -+0x0CA4, -+0x0C37, -+0x0807, -+0x0C64, -+0x8D18, -+0x080F, -+0x03E0, -+0x0182, -+0x0006, -+0x33AF, -+0x0807, -+0x0C6C, -+0x8CD9, -+0x080E, -+0x00FF, -+0x13E8, -+0x33AE, -+0x0D4D, -+0x55AC, -+0x31A2, -+0x080E, -+0xFF00, -+0x13E8, -+0x33AE, -+0x0D4D, -+0x55AC, -+0x31A5, -+0x0807, -+0x0C7D, -+0x8DF4, -+0xAC83, -+0x5062, -+0x31A2, -+0x5065, -+0x31A5, -+0x8C8B, -+0x5462, -+0x31A2, -+0xBC87, -+0x0C02, -+0x5465, -+0x31A5, -+0xBC8B, -+0x0C05, -+0x0C0D, -+0x304D, -+0x43ED, -+0xAC96, -+0x304D, -+0x430D, -+0xAC93, -+0x8C97, -+0x0802, -+0x00FF, -+0x8C97, -+0x0C02, -+0x30AD, -+0x43ED, -+0xACA1, -+0x30AD, -+0x430D, -+0xAC9E, -+0x8CA2, -+0x0805, -+0x00FF, -+0x8CA2, -+0x0C05, -+0x0807, -+0x0CA5, -+0x8CCB, -+0x0800, -+0x0349, -+0x0802, -+0x034A, -+0x0803, -+0x01B4, -+0x3818, -+0x0801, -+0x002F, -+0x0D44, -+0x0C17, -+0x0807, -+0x0CB3, -+0x8D18, -+0x080F, -+0x03E0, -+0x0182, -+0x0004, -+0x33AF, -+0x0807, -+0x0CBB, -+0x8CD9, -+0x0800, -+0x0349, -+0x0802, -+0x034A, -+0x0803, -+0x01B4, -+0x3818, -+0x0C01, -+0x0CA4, -+0x0C37, -+0x0807, -+0x0CC8, -+0x8D18, -+0x33FE, -+0x0C1F, -+0x896A, -+0xD9AE, -+0x01AF, -+0x0016, -+0x304D, -+0x29AD, -+0xD9B6, -+0x01AF, -+0x0018, -+0x30AD, -+0x29AD, -+0xD9B6, -+0x700F, -+0xD1AE, -+0x9007, -+0x080F, -+0x7FFF, -+0x0180, -+0x07CF, -+0x33AF, -+0x0181, -+0xFFFF, -+0x0FEF, -+0x0182, -+0x0006, -+0x080F, -+0x4000, -+0xD984, -+0x080F, -+0x1C00, -+0x0184, -+0x0004, -+0x080F, -+0x0020, -+0xD984, -+0x0F0F, -+0xD184, -+0x33AF, -+0x080F, -+0x03C0, -+0xD184, -+0x33AF, -+0x080F, -+0x0800, -+0xD183, -+0x33AF, -+0x0E81, -+0x6660, -+0x080E, -+0x7FFF, -+0x198A, -+0x33AE, -+0x31A2, -+0x080E, -+0x7FFF, -+0x1986, -+0x33AE, -+0x544D, -+0x31A2, -+0x080E, -+0xFF00, -+0x1BE9, -+0x33AE, -+0x504D, -+0x31A2, -+0x430D, -+0xAD0E, -+0x8D10, -+0x0802, -+0x00FF, -+0x304D, -+0x080F, -+0xFF00, -+0x2BE9, -+0x33AF, -+0x5C21, -+0xACF9, -+0x9007, -+0x3805, -+0x0CED, -+0x52ED, -+0x54AD, -+0xAD1E, -+0x8D39, -+0x0DED, -+0x52ED, -+0x54AD, -+0xAD23, -+0x8D39, -+0x0EED, -+0x52ED, -+0x54AD, -+0xAD28, -+0x8D39, -+0x0FED, -+0x52ED, -+0x54AD, -+0xAD2D, -+0x8D39, -+0x080D, -+0x0027, -+0x52ED, -+0x54AD, -+0xAD33, -+0x8D39, -+0x308D, -+0xAD36, -+0x8D46, -+0x5C24, -+0x31A4, -+0x8D3E, -+0x32ED, -+0xAD3E, -+0x308D, -+0xAD3E, -+0x8D46, -+0x32ED, -+0xAD42, -+0x5A20, -+0x8D43, -+0x5E20, -+0x3C43, -+0xD9B8, -+0x8D18, -+0x9007, -+0x1959, -+0x1959, -+0x31A1, -+0x0800, -+0x3000, -+0x5401, -+0xBD54, -+0x0800, -+0x1000, -+0x5420, -+0xBD54, -+0x0C25, -+0x8D5C, -+0x1B5E, -+0xAD59, -+0x0807, -+0x0D59, -+0x8917, -+0x0C05, -+0x0C04, -+0x8DEC, -+0x080E, -+0x00FF, -+0x1BE9, -+0x33AE, -+0x31A0, -+0x080E, -+0xFF00, -+0x13EA, -+0x080E, -+0x00FF, -+0x1BEA, -+0x33AE, -+0x51AC, -+0xBD6C, -+0x0C01, -+0x8D73, -+0x31A1, -+0x0804, -+0x002A, -+0x55A4, -+0xBD73, -+0x0801, -+0x002A, -+0x302D, -+0x080F, -+0x00FF, -+0x2BEB, -+0x33AF, -+0x0807, -+0x0D7B, -+0x8DF4, -+0xAD7E, -+0x0C03, -+0x8D7F, -+0x4223, -+0x080E, -+0x0FE0, -+0x196F, -+0x33AE, -+0x31A2, -+0x0804, -+0x0040, -+0x5482, -+0xBD89, -+0x0C0D, -+0x31A2, -+0x4222, -+0x5062, -+0x55A0, -+0x31A0, -+0x0C04, -+0x0C2E, -+0x1BEB, -+0xAD93, -+0x8D96, -+0x300D, -+0x51A4, -+0x31A4, -+0x0C4E, -+0x1BEB, -+0xAD9A, -+0x8D9E, -+0x300D, -+0x442D, -+0x51A4, -+0x31A4, -+0x0C8E, -+0x1BEB, -+0xADA2, -+0x8DA6, -+0x300D, -+0x444D, -+0x51A4, -+0x31A4, -+0x0D0E, -+0x1BEB, -+0xADAA, -+0x8DAE, -+0x300D, -+0x446D, -+0x51A4, -+0x31A4, -+0x0E0E, -+0x1BEB, -+0xADB2, -+0x8DB6, -+0x300D, -+0x448D, -+0x51A4, -+0x31A4, -+0x080E, -+0x0020, -+0x1BEB, -+0xADBB, -+0x8DBF, -+0x300D, -+0x44AD, -+0x51A4, -+0x31A4, -+0x33AE, -+0x308D, -+0x46AD, -+0x31A4, -+0x080E, -+0xFF00, -+0x1BE9, -+0x33AE, -+0x31A1, -+0x1B5E, -+0xADDC, -+0x0CA0, -+0x5401, -+0xBDD0, -+0x0805, -+0x0060, -+0x8DDD, -+0x0D40, -+0x5401, -+0xBDD6, -+0x0805, -+0x0040, -+0x8DDD, -+0x0DE0, -+0x5401, -+0xBDDC, -+0x0805, -+0x0020, -+0x8DDD, -+0x0C05, -+0x5085, -+0x31A4, -+0x0C0D, -+0x308D, -+0x43ED, -+0xADE4, -+0x8DE6, -+0x0C04, -+0x8DEC, -+0x308D, -+0x430D, -+0xADEA, -+0x8DEC, -+0x0804, -+0x00FF, -+0x1B5E, -+0xADF2, -+0x308D, -+0x33FE, -+0x0C1F, -+0x8972, -+0x308D, -+0x8048, -+0x080E, -+0x1FE0, -+0x196E, -+0x33AE, -+0x31A3, -+0x080E, -+0x1000, -+0x196E, -+0x33AE, -+0x31A4, -+0xAE00, -+0x8E04, -+0x080D, -+0x0100, -+0x546D, -+0x31A3, -+0x308D, -+0x9007, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000, -+0x0000 ---- a/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c -+++ b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c -@@ -20,6 +20,7 @@ - - /* Register for RK3568 */ - #define GRF_PCIE30PHY_CON1 0x4 -+#define GRF_PCIE30PHY_CON4 0x10 - #define GRF_PCIE30PHY_CON6 0x18 - #define GRF_PCIE30PHY_CON9 0x24 - #define GRF_PCIE30PHY_STATUS0 0x80 -@@ -61,6 +62,10 @@ struct rockchip_p3phy_ops { - int (*phy_init)(struct rockchip_p3phy_priv *priv); - }; - -+static u16 phy_fw[] = { -+ #include "p3phy.fw" -+}; -+ - static int rockchip_p3phy_set_mode(struct phy *phy, enum phy_mode mode, int submode) - { - struct rockchip_p3phy_priv *priv = phy_get_drvdata(phy); -@@ -86,6 +91,7 @@ static int rockchip_p3phy_rk3568_init(st - struct phy *phy = priv->phy; - bool bifurcation = false; - int ret; -+ int i; - u32 reg; - - /* Deassert PCIe PMA output clamp mode */ -@@ -110,16 +116,35 @@ static int rockchip_p3phy_rk3568_init(st - (0xf << 16) & ~RK3568_BIFURCATION_LANE_0_1); - } - -+ regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON4, -+ (0x0 << 14) | (0x1 << (14 + 16))); //sdram_ld_done -+ regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON4, -+ (0x0 << 13) | (0x1 << (13 + 16))); //sdram_bypass -+ - reset_control_deassert(priv->p30phy); - - ret = regmap_read_poll_timeout(priv->phy_grf, - GRF_PCIE30PHY_STATUS0, - reg, SRAM_INIT_DONE(reg), - 0, 500); -- if (ret) -+ if (ret) { - dev_err(&priv->phy->dev, "%s: lock failed 0x%x, check input refclk and power supply\n", - __func__, reg); - return ret; -+ } -+ -+ regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON9, -+ (0x3 << 8) | (0x3 << (8 + 16))); //map to access sram -+ for (i = 0; i < 8192; i++) -+ writel(phy_fw[i], priv->mmio + (i<<2)); -+ -+ regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON9, -+ (0x0 << 8) | (0x3 << (8 + 16))); -+ regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON4, -+ (0x1 << 14) | (0x1 << (14 + 16))); //sdram_ld_done -+ -+ dev_info(&priv->phy->dev, "p3phy (fw-d54d0eb) initialized\n"); -+ return 0; - } - - static const struct rockchip_p3phy_ops rk3568_ops = {