diff options
author | Vagrant Cascadian <vagrant@debian.org> | 2025-03-15 19:05:09 -0700 |
---|---|---|
committer | Vagrant Cascadian <vagrant@debian.org> | 2025-03-16 18:45:47 -0700 |
commit | 9d1e2ad4192baa53d2740e586cbed2beff64ac5c (patch) | |
tree | ad66b3caa3050de5b9a02d34c9ebf808838db5aa | |
parent | b3d9720c5c4a929e1ba13343e6a79ab61b764064 (diff) |
gnu: linux-libre-arm64-mnt-reform: Use patches from git repository.
* gnu/packages/linux.scm (linux-libre-mnt-reform-6.12-source): Remove variable
(reform-debian-packages): New variable.
(linux-libre-arm64-mnt-reform)[source]: Use linux-libre-6.12-source.
[inputs]: Add reform-debian-packages.
[phases]: Add 'apply-reform-patches, 'copy-rockchip-dts-files, 'copy-freescale-dts-files, 'copy-amlogic-dts-files
and 'adjust-makefiles-with-new-dtb.
* gnu/packages/patches/reform/dts.patch: Remove file.
* gnu/packages/patches/reform/imx8mp-mnt-pocket-reform/2ghz/0001-imx8mp-2ghz-clk.patch: Remove file.
* gnu/packages/patches/reform/imx8mp-mnt-pocket-reform/2ghz/0002-imx8mp-2ghz-opp.patch: Remove file.
* gnu/packages/patches/reform/imx8mp-mnt-pocket-reform/audio/0000-revert-crashy-audiomix-pm-support.patch: Remove file.
* gnu/packages/patches/reform/imx8mp-mnt-pocket-reform/mmc-sdio/0001-sdhci-add-no-sd-uhs-sdr104-devicetree-property.patch: Remove file.
* gnu/packages/patches/reform/imx8mp-mnt-pocket-reform/mmc-sdio/0002-During-the-card-init-the-host-side-sometimes-may-nee.patch: Remove file.
* gnu/packages/patches/reform/imx8mp-mnt-pocket-reform/mmc-sdio/0003-USDHC-IP-has-one-limitation-the-tuning-circuit-can-t.patch: Remove file.
* gnu/packages/patches/reform/imx8mp-mnt-pocket-reform/pocket-panel/0001-v5-add-multi-display-panel-driver.patch: Remove file.
* gnu/packages/patches/reform/imx8mp-mnt-reform2/0001-sn65dsi86-use-hs-clock-of-samsung-dsim-host-directly.patch: Remove file.
* gnu/packages/patches/reform/imx8mp-mnt-reform2/0002-lcdif-dont-exceed-desired-pixel-clock.patch: Remove file.
* gnu/packages/patches/reform/imx8mq-mnt-reform2/0001-nwl-dsi-fixup-mode-only-for-LCDIF-input-not-DCSS.patch: Remove file.
* gnu/packages/patches/reform/imx8mq-mnt-reform2/0002-pci-imx6-add-support-for-internal-refclk-imx8mq.patch: Remove file.
* gnu/packages/patches/reform/imx8mq-mnt-reform2/0003-lcdif-fix-pcie-interference.patch: Remove file.
* gnu/packages/patches/reform/imx8mq-mnt-reform2/0004-mnt4002-imx-gpcv2-wake-smccc.patch.patch: Remove file.
* gnu/packages/patches/reform/imx8mq-mnt-reform2/v19_20241126_sandor_yu_initial_support_cadence_mhdp8501_hdmi_dp_for_i_mx8mq.mbx: Remove file.
* gnu/packages/patches/reform/ls1028a-mnt-reform2/0000-dtsi-add-hdptx.patch: Remove file.
* gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-pocket-reform/0001-a311d-viu-fifo-lines-config.patch: Remove file.
* gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-pocket-reform/0002-a311d-viu-fifo-lines-config-header.patch: Remove file.
* gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-pocket-reform/0003-tlv320aic31xx-add-1228800hz-support.patch: Remove file.
* gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0001-Revert-drm-bridge-synopsys-dw-mipi-dsi-enable-EoTp-b.patch: Remove file.
* gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0011-dw-mipi-dsi-phy-stop-wait-time.patch: Remove file.
* gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0012-innolux-n125hce-gn1-timing-tweaks.patch: Remove file.
* gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0013-meson-viu-hold-fifo-lines.patch: Remove file.
* gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0014-meson-venc-sync.patch.patch: Remove file.
* gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0015-meson-dw-mipi-dsi-sync-invert.patch: Remove file.
* gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0016-sn65dsi86-burst-mode-support.patch: Remove file.
* gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0018-sn65dsi86-never-turn-off.patch: Remove file.
* gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0020-LOCAL-ALSA-Assign-internal-PCM-chmap-ELD-IEC958-kctl.patch: Remove file.
* gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0021-HACK-of-partial-revert-of-fdt.c-changes.patch: Remove file.
* gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0022-add-bt-and-eth-resets.patch: Remove file.
* gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0023-sdio-pullups.patch: Remove file.
* gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0024-sdio-improve-wifi-speed.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0001-regulator-Add-of_regulator_get_optional-for-pure-DT-.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0001-scripts-package-builddeb-allow-hooks-also-in-usr-sha.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0002-regulator-Add-devres-version-of-of_regulator_get_opt.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0004-arm64-dts-rockchip-rk3588-rock5b-add-USB-C-support.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0005-math.h-add-DIV_ROUND_UP_NO_OVERFLOW.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0006-clk-divider-Fix-divisor-masking-on-64-bit-platforms.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0007-clk-composite-replace-open-coded-abs_diff.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0008-clk-rockchip-support-clocks-registered-late.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0009-clk-rockchip-rk3588-register-GATE_LINK-later.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0010-clk-rockchip-expose-rockchip_clk_set_lookup.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0011-clk-rockchip-implement-linked-gate-clock-support.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0012-clk-rockchip-rk3588-drop-RK3588_LINKED_CLK.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0013-arm64-dts-rockchip-rk3588-evb1-add-bluetooth-rfkill.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0014-arm64-dts-rockchip-rk3588-evb1-improve-PCIe-ethernet.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0015-arm64-dts-rockchip-Slow-down-EMMC-a-bit-to-keep-IO-s.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0016-vop2-Add-clock-resets-support.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0017-arm64-dts-rockchip-Add-VOP-clock-resets-for-rk3588s.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0018-dt-bindings-display-vop2-Add-VP-clock-resets.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0019-media-v4l2-ctrls-core-Set-frame_mbs_only_flag-by-def.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0020-media-rockchip-Move-H264-CABAC-table-to-header-file.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0021-media-rockchip-Introduce-the-rkvdec2-driver.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0022-media-dt-bindings-rockchip-Document-RK3588-Video-Dec.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0023-arm64-dts-rockchip-Add-rkvdec2-Video-Decoder-on-rk35.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0024-arm64-defconfig-enable-Rockchip-RK3588-video-decoder.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0025-mfd-rk8xx-Fix-shutdown-handler.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0026-WIP-phy-phy-rockchip-samsung-hdptx-Add-FRL-EARC-supp.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0027-TESTING-phy-phy-rockchip-samsung-hdptx-Add-verbose-l.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0028-WIP-dt-bindings-display-rockchip-drm-Add-optional-cl.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0029-WIP-drm-rockchip-vop2-Improve-display-modes-handling.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0030-arm64-dts-rockchip-Add-HDMI0-bridge-to-rk3588.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0031-arm64-dts-rockchip-Enable-HDMI0-on-rock-5b.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0032-arm64-dts-rockchip-Enable-HDMI0-on-rk3588-evb1.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0033-WIP-arm64-dts-rockchip-Enable-HDMI0-PHY-clk-provider.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0034-WIP-arm64-dts-rockchip-Make-use-of-HDMI0-PHY-PLL-on-.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0035-WIP-arm64-dts-rockchip-Make-use-of-HDMI0-PHY-PLL-on-.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0036-dt-bindings-display-bridge-Add-schema-for-Synopsys-D.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0037-dt-bindings-display-rockchip-Add-schema-for-RK3588-H.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0038-drm-bridge-synopsys-Add-DW-HDMI-QP-TX-controller-dri.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0039-drm-rockchip-Add-basic-RK3588-HDMI-output-support.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0040-arm64-defconfig-Enable-Rockchip-extensions-for-Synop.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0041-MAINTAINERS-Add-entry-for-Synopsys-DesignWare-HDMI-R.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0042-dt-bindings-media-Document-bindings-for-HDMI-RX-Cont.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0043-arm64-dts-rockchip-Add-device-tree-support-for-HDMI-.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0044-media-platform-synopsys-Add-support-for-HDMI-input-d.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0045-arm64-defconfig-Enable-Synopsys-HDMI-receiver.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0046-arm64-dts-rockchip-Enable-HDMI-receiver-on-rock-5b.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0047-arm64-dts-rockchip-Enable-HDMI-receiver-on-RK3588-EV.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0048-arm64-defconfig-Enable-default-EDID-for-Synopsys-HDM.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0049-regulator-Add-devm_-of_regulator_get.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0050-pmdomain-rockchip-cleanup-mutex-handling-in-rockchip.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0051-pmdomain-rockchip-forward-rockchip_do_pmu_set_power_.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0052-pmdomain-rockchip-reduce-indentation-in-rockchip_pd_.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0053-dt-bindings-power-rockchip-add-regulator-support.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0054-pmdomain-rockchip-add-regulator-support.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0055-arm64-dts-rockchip-Add-GPU-power-domain-regulator-de.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0056-dt-bindings-net-wireless-brcm4329-fmac-add-pci14e4-4.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0057-dt-bindings-net-wireless-brcm4329-fmac-add-clock-des.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0058-wifi-brcmfmac-Add-optional-lpo-clock-enable-support.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0059-wifi-brcmfmac-add-flag-for-random-seed-during-firmwa.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0060-arm64-dts-rockchip-rk3588-evb1-add-WLAN-controller.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0061-arm64-dts-rockchip-add-and-enable-gpu-node-for-Radxa.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0062-arm64-dts-rockchip-Enable-HDMI0-on-rock-5a.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0100-rk3588-dtsi-add-hdmi1-controller.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/0102-drm-panthor-Actually-suspend-IRQs-in-the-unplug-path.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/3001-display-rockchip-add-schema-for-rk3588-hdmi-tx.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/4000-mnt-rk3588-dual-hdmi-qp-rockchip.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/4001-mnt-rk3588-dual-hdmi-vop2-pll.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/5001-rk3588-dsi2-driver.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/5002-rk3588-dsi-dts-nodes.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/5100-modernize-hdmi1-in-dtsi.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/5110-hdptx-crash-workaround.patch: Remove file.
* gnu/packages/patches/reform/rk3588-mnt-reform2/5200-drm-rockchip-Set-dma-mask-to-64-bit.patch: Remove file.
105 files changed, 225 insertions, 36466 deletions
diff --git a/gnu/packages/linux.scm b/gnu/packages/linux.scm index d954be8a15..a27a5c38cd 100644 --- a/gnu/packages/linux.scm +++ b/gnu/packages/linux.scm @@ -1463,127 +1463,51 @@ Linux kernel. It has been modified to remove all non-free binary blobs.") ("CONFIG_VHOST_VDPA" . m)) (default-extra-linux-options linux-libre-lts-version)))) -(define-public linux-libre-mnt-reform-6.12-source - (source-with-patches linux-libre-6.12-pristine-source - (append - ;; Patches taken from - ;; https://source.mnt.re/reform/reform-debian-packages/-/tree/278f964619e597bf0b3aae67fef52bb541bc89e6/linux/patches6.12/ - (search-patches - "reform/imx8mp-mnt-pocket-reform/2ghz/0001-imx8mp-2ghz-clk.patch" - "reform/imx8mp-mnt-pocket-reform/2ghz/0002-imx8mp-2ghz-opp.patch" - "reform/imx8mp-mnt-pocket-reform/audio/0000-revert-crashy-audiomix-pm-support.patch" - "reform/imx8mp-mnt-pocket-reform/mmc-sdio/0001-sdhci-add-no-sd-uhs-sdr104-devicetree-property.patch" - "reform/imx8mp-mnt-pocket-reform/mmc-sdio/0002-During-the-card-init-the-host-side-sometimes-may-nee.patch" - "reform/imx8mp-mnt-pocket-reform/mmc-sdio/0003-USDHC-IP-has-one-limitation-the-tuning-circuit-can-t.patch" - "reform/imx8mp-mnt-pocket-reform/pocket-panel/0001-v5-add-multi-display-panel-driver.patch" - "reform/imx8mp-mnt-reform2/0001-sn65dsi86-use-hs-clock-of-samsung-dsim-host-directly.patch" - "reform/imx8mp-mnt-reform2/0002-lcdif-dont-exceed-desired-pixel-clock.patch" - "reform/imx8mq-mnt-reform2/0001-nwl-dsi-fixup-mode-only-for-LCDIF-input-not-DCSS.patch" - "reform/imx8mq-mnt-reform2/0002-pci-imx6-add-support-for-internal-refclk-imx8mq.patch" - "reform/imx8mq-mnt-reform2/0003-lcdif-fix-pcie-interference.patch" - "reform/imx8mq-mnt-reform2/0004-mnt4002-imx-gpcv2-wake-smccc.patch.patch" - ;; Does not apply, needs further investigation - ;; "reform/imx8mq-mnt-reform2/v19_20241126_sandor_yu_initial_support_cadence_mhdp8501_hdmi_dp_for_i_mx8mq.mbx" - "reform/ls1028a-mnt-reform2/0000-dtsi-add-hdptx.patch" - "reform/meson-g12b-bananapi-cm4-mnt-pocket-reform/0001-a311d-viu-fifo-lines-config.patch" - "reform/meson-g12b-bananapi-cm4-mnt-pocket-reform/0002-a311d-viu-fifo-lines-config-header.patch" - "reform/meson-g12b-bananapi-cm4-mnt-pocket-reform/0003-tlv320aic31xx-add-1228800hz-support.patch" - "reform/meson-g12b-bananapi-cm4-mnt-reform2/0001-Revert-drm-bridge-synopsys-dw-mipi-dsi-enable-EoTp-b.patch" - "reform/meson-g12b-bananapi-cm4-mnt-reform2/0011-dw-mipi-dsi-phy-stop-wait-time.patch" - "reform/meson-g12b-bananapi-cm4-mnt-reform2/0012-innolux-n125hce-gn1-timing-tweaks.patch" - "reform/meson-g12b-bananapi-cm4-mnt-reform2/0013-meson-viu-hold-fifo-lines.patch" - "reform/meson-g12b-bananapi-cm4-mnt-reform2/0014-meson-venc-sync.patch.patch" - "reform/meson-g12b-bananapi-cm4-mnt-reform2/0015-meson-dw-mipi-dsi-sync-invert.patch" - "reform/meson-g12b-bananapi-cm4-mnt-reform2/0016-sn65dsi86-burst-mode-support.patch" - "reform/meson-g12b-bananapi-cm4-mnt-reform2/0018-sn65dsi86-never-turn-off.patch" - "reform/meson-g12b-bananapi-cm4-mnt-reform2/0020-LOCAL-ALSA-Assign-internal-PCM-chmap-ELD-IEC958-kctl.patch" - "reform/meson-g12b-bananapi-cm4-mnt-reform2/0021-HACK-of-partial-revert-of-fdt.c-changes.patch" - "reform/meson-g12b-bananapi-cm4-mnt-reform2/0022-add-bt-and-eth-resets.patch" - "reform/meson-g12b-bananapi-cm4-mnt-reform2/0023-sdio-pullups.patch" - "reform/meson-g12b-bananapi-cm4-mnt-reform2/0024-sdio-improve-wifi-speed.patch" - "reform/rk3588-mnt-reform2/0001-regulator-Add-of_regulator_get_optional-for-pure-DT-.patch" - "reform/rk3588-mnt-reform2/0001-scripts-package-builddeb-allow-hooks-also-in-usr-sha.patch" - "reform/rk3588-mnt-reform2/0002-regulator-Add-devres-version-of-of_regulator_get_opt.patch" - "reform/rk3588-mnt-reform2/0004-arm64-dts-rockchip-rk3588-rock5b-add-USB-C-support.patch" - "reform/rk3588-mnt-reform2/0005-math.h-add-DIV_ROUND_UP_NO_OVERFLOW.patch" - "reform/rk3588-mnt-reform2/0006-clk-divider-Fix-divisor-masking-on-64-bit-platforms.patch" - "reform/rk3588-mnt-reform2/0007-clk-composite-replace-open-coded-abs_diff.patch" - "reform/rk3588-mnt-reform2/0008-clk-rockchip-support-clocks-registered-late.patch" - "reform/rk3588-mnt-reform2/0009-clk-rockchip-rk3588-register-GATE_LINK-later.patch" - "reform/rk3588-mnt-reform2/0010-clk-rockchip-expose-rockchip_clk_set_lookup.patch" - "reform/rk3588-mnt-reform2/0011-clk-rockchip-implement-linked-gate-clock-support.patch" - "reform/rk3588-mnt-reform2/0012-clk-rockchip-rk3588-drop-RK3588_LINKED_CLK.patch" - "reform/rk3588-mnt-reform2/0013-arm64-dts-rockchip-rk3588-evb1-add-bluetooth-rfkill.patch" - "reform/rk3588-mnt-reform2/0014-arm64-dts-rockchip-rk3588-evb1-improve-PCIe-ethernet.patch" - "reform/rk3588-mnt-reform2/0015-arm64-dts-rockchip-Slow-down-EMMC-a-bit-to-keep-IO-s.patch" - "reform/rk3588-mnt-reform2/0016-vop2-Add-clock-resets-support.patch" - "reform/rk3588-mnt-reform2/0017-arm64-dts-rockchip-Add-VOP-clock-resets-for-rk3588s.patch" - "reform/rk3588-mnt-reform2/0018-dt-bindings-display-vop2-Add-VP-clock-resets.patch" - "reform/rk3588-mnt-reform2/0019-media-v4l2-ctrls-core-Set-frame_mbs_only_flag-by-def.patch" - "reform/rk3588-mnt-reform2/0020-media-rockchip-Move-H264-CABAC-table-to-header-file.patch" - "reform/rk3588-mnt-reform2/0021-media-rockchip-Introduce-the-rkvdec2-driver.patch" - "reform/rk3588-mnt-reform2/0022-media-dt-bindings-rockchip-Document-RK3588-Video-Dec.patch" - "reform/rk3588-mnt-reform2/0023-arm64-dts-rockchip-Add-rkvdec2-Video-Decoder-on-rk35.patch" - "reform/rk3588-mnt-reform2/0024-arm64-defconfig-enable-Rockchip-RK3588-video-decoder.patch" - "reform/rk3588-mnt-reform2/0025-mfd-rk8xx-Fix-shutdown-handler.patch" - "reform/rk3588-mnt-reform2/0026-WIP-phy-phy-rockchip-samsung-hdptx-Add-FRL-EARC-supp.patch" - "reform/rk3588-mnt-reform2/0027-TESTING-phy-phy-rockchip-samsung-hdptx-Add-verbose-l.patch" - "reform/rk3588-mnt-reform2/0028-WIP-dt-bindings-display-rockchip-drm-Add-optional-cl.patch" - "reform/rk3588-mnt-reform2/0029-WIP-drm-rockchip-vop2-Improve-display-modes-handling.patch" - "reform/rk3588-mnt-reform2/0030-arm64-dts-rockchip-Add-HDMI0-bridge-to-rk3588.patch" - "reform/rk3588-mnt-reform2/0031-arm64-dts-rockchip-Enable-HDMI0-on-rock-5b.patch" - "reform/rk3588-mnt-reform2/0032-arm64-dts-rockchip-Enable-HDMI0-on-rk3588-evb1.patch" - "reform/rk3588-mnt-reform2/0033-WIP-arm64-dts-rockchip-Enable-HDMI0-PHY-clk-provider.patch" - "reform/rk3588-mnt-reform2/0034-WIP-arm64-dts-rockchip-Make-use-of-HDMI0-PHY-PLL-on-.patch" - "reform/rk3588-mnt-reform2/0035-WIP-arm64-dts-rockchip-Make-use-of-HDMI0-PHY-PLL-on-.patch" - "reform/rk3588-mnt-reform2/0036-dt-bindings-display-bridge-Add-schema-for-Synopsys-D.patch" - "reform/rk3588-mnt-reform2/0037-dt-bindings-display-rockchip-Add-schema-for-RK3588-H.patch" - "reform/rk3588-mnt-reform2/0038-drm-bridge-synopsys-Add-DW-HDMI-QP-TX-controller-dri.patch" - "reform/rk3588-mnt-reform2/0039-drm-rockchip-Add-basic-RK3588-HDMI-output-support.patch" - "reform/rk3588-mnt-reform2/0040-arm64-defconfig-Enable-Rockchip-extensions-for-Synop.patch" - "reform/rk3588-mnt-reform2/0041-MAINTAINERS-Add-entry-for-Synopsys-DesignWare-HDMI-R.patch" - "reform/rk3588-mnt-reform2/0042-dt-bindings-media-Document-bindings-for-HDMI-RX-Cont.patch" - "reform/rk3588-mnt-reform2/0043-arm64-dts-rockchip-Add-device-tree-support-for-HDMI-.patch" - "reform/rk3588-mnt-reform2/0044-media-platform-synopsys-Add-support-for-HDMI-input-d.patch" - "reform/rk3588-mnt-reform2/0045-arm64-defconfig-Enable-Synopsys-HDMI-receiver.patch" - "reform/rk3588-mnt-reform2/0046-arm64-dts-rockchip-Enable-HDMI-receiver-on-rock-5b.patch" - "reform/rk3588-mnt-reform2/0047-arm64-dts-rockchip-Enable-HDMI-receiver-on-RK3588-EV.patch" - "reform/rk3588-mnt-reform2/0048-arm64-defconfig-Enable-default-EDID-for-Synopsys-HDM.patch" - "reform/rk3588-mnt-reform2/0049-regulator-Add-devm_-of_regulator_get.patch" - "reform/rk3588-mnt-reform2/0050-pmdomain-rockchip-cleanup-mutex-handling-in-rockchip.patch" - "reform/rk3588-mnt-reform2/0051-pmdomain-rockchip-forward-rockchip_do_pmu_set_power_.patch" - "reform/rk3588-mnt-reform2/0052-pmdomain-rockchip-reduce-indentation-in-rockchip_pd_.patch" - "reform/rk3588-mnt-reform2/0053-dt-bindings-power-rockchip-add-regulator-support.patch" - "reform/rk3588-mnt-reform2/0054-pmdomain-rockchip-add-regulator-support.patch" - "reform/rk3588-mnt-reform2/0055-arm64-dts-rockchip-Add-GPU-power-domain-regulator-de.patch" - "reform/rk3588-mnt-reform2/0056-dt-bindings-net-wireless-brcm4329-fmac-add-pci14e4-4.patch" - "reform/rk3588-mnt-reform2/0057-dt-bindings-net-wireless-brcm4329-fmac-add-clock-des.patch" - "reform/rk3588-mnt-reform2/0058-wifi-brcmfmac-Add-optional-lpo-clock-enable-support.patch" - ;; does not apply cleanly due to DEBLOBBING - ;; "reform/rk3588-mnt-reform2/0059-wifi-brcmfmac-add-flag-for-random-seed-during-firmwa.patch" - "reform/rk3588-mnt-reform2/0060-arm64-dts-rockchip-rk3588-evb1-add-WLAN-controller.patch" - "reform/rk3588-mnt-reform2/0061-arm64-dts-rockchip-add-and-enable-gpu-node-for-Radxa.patch" - "reform/rk3588-mnt-reform2/0062-arm64-dts-rockchip-Enable-HDMI0-on-rock-5a.patch" - "reform/rk3588-mnt-reform2/0100-rk3588-dtsi-add-hdmi1-controller.patch" - "reform/rk3588-mnt-reform2/0102-drm-panthor-Actually-suspend-IRQs-in-the-unplug-path.patch" - "reform/rk3588-mnt-reform2/3001-display-rockchip-add-schema-for-rk3588-hdmi-tx.patch" - "reform/rk3588-mnt-reform2/4000-mnt-rk3588-dual-hdmi-qp-rockchip.patch" - "reform/rk3588-mnt-reform2/4001-mnt-rk3588-dual-hdmi-vop2-pll.patch" - "reform/rk3588-mnt-reform2/5001-rk3588-dsi2-driver.patch" - "reform/rk3588-mnt-reform2/5002-rk3588-dsi-dts-nodes.patch" - "reform/rk3588-mnt-reform2/5100-modernize-hdmi1-in-dtsi.patch" - "reform/rk3588-mnt-reform2/5110-hdptx-crash-workaround.patch" - "reform/rk3588-mnt-reform2/5200-drm-rockchip-Set-dma-mask-to-64-bit.patch" - "reform/dts.patch") - (list %boot-logo-patch - %linux-libre-arm-export-__sync_icache_dcache-patch)))) +(define-public reform-debian-packages + (package + (name "reform-debian-packages") + (version "278f964619e597bf0b3aae67fef52bb541bc89e6") + (source + (origin + (method git-fetch) + (uri (git-reference + (url "https://source.mnt.re/reform/reform-debian-packages.git") + (commit version))) + (file-name (git-file-name name version)) + (sha256 + (base32 "19phz43ar2p9w0rq2pgzjx8zbxy2hppjbprvw95dvbkm8a20gv5v")))) + (build-system copy-build-system) + (arguments + (list ;; #:tests? #f ; no tests + #:install-plan + #~'(("linux/patches6.12/" "/patches") + ("linux/" "/dts" #:include-regexp ("\\.dts$")) + ("linux/config" "config") + ))) + (home-page "https://source.mnt.re/reform/reform-debian-packages") + (synopsis "Linux kernel patches and device-trees used for MNT Reform systems") + (description + "Linux kernel patches and device-trees used for the MNT Reform systems") + + ;; FSFAP GPL-2.0 GPL-2.0+ GPL-2.0-only (GPL-2.0-only OR BSD-2-Clause) + ;; GPL-2.0-only OR BSD-2-Clause (GPL-2.0 OR BSD-2-Clause) GPL-2.0-or-later + ;; GPL-2.0 or MIT (GPL-2.0+ OR MIT) (GPL-3.0 OR BSD-2-Clause) MIT + (license + (list + license:bsd-2 + license:gpl2 + license:gpl2+ + license:gpl3 + ;; license:mit + ;; license:FSFAP + )))) (define-public linux-libre-arm64-mnt-reform ;; Kernel for use on the MNT/Reform laptops ;; https://mntre.com/reform.html - (make-linux-libre* linux-libre-6.12-version + (let ((base (make-linux-libre* linux-libre-6.12-version linux-libre-6.12-gnu-revision - linux-libre-mnt-reform-6.12-source + linux-libre-6.12-source '("aarch64-linux") #:extra-version "arm64-mnt-reform" #:extra-options @@ -1670,7 +1594,191 @@ Linux kernel. It has been modified to remove all non-free binary blobs.") ("CONFIG_VIDEO_ROCKCHIP_VDEC2" . m) ("CONFIG_ROCKCHIP_DW_HDMI_QP" . #true) ("CONFIG_ROCKCHIP_DW_MIPI_DSI" . #true)) - (default-extra-linux-options linux-libre-6.12-version)))) + (default-extra-linux-options linux-libre-6.12-version))))) + (package + (inherit base) + (inputs (list reform-debian-packages)) + (arguments + (substitute-keyword-arguments + (package-arguments base) + ((#:phases phases) + #~(modify-phases #$phases + (add-after 'unpack 'apply-reform-patches + (lambda* (#:key inputs #:allow-other-keys) + (for-each (lambda (patch) + (invoke "patch" "-p1" "--force" "-i" + (search-input-file + inputs + (string-append "patches/" patch)))) + (list + "imx8mp-mnt-pocket-reform/2ghz/0001-imx8mp-2ghz-clk.patch" + "imx8mp-mnt-pocket-reform/2ghz/0002-imx8mp-2ghz-opp.patch" + "imx8mp-mnt-pocket-reform/audio/0000-revert-crashy-audiomix-pm-support.patch" + "imx8mp-mnt-pocket-reform/mmc-sdio/0001-sdhci-add-no-sd-uhs-sdr104-devicetree-property.patch" + "imx8mp-mnt-pocket-reform/mmc-sdio/0002-During-the-card-init-the-host-side-sometimes-may-nee.patch" + "imx8mp-mnt-pocket-reform/mmc-sdio/0003-USDHC-IP-has-one-limitation-the-tuning-circuit-can-t.patch" + "imx8mp-mnt-pocket-reform/pocket-panel/0001-v5-add-multi-display-panel-driver.patch" + "imx8mp-mnt-reform2/0001-sn65dsi86-use-hs-clock-of-samsung-dsim-host-directly.patch" + "imx8mp-mnt-reform2/0002-lcdif-dont-exceed-desired-pixel-clock.patch" + "imx8mq-mnt-reform2/0001-nwl-dsi-fixup-mode-only-for-LCDIF-input-not-DCSS.patch" + "imx8mq-mnt-reform2/0002-pci-imx6-add-support-for-internal-refclk-imx8mq.patch" + "imx8mq-mnt-reform2/0003-lcdif-fix-pcie-interference.patch" + "imx8mq-mnt-reform2/0004-mnt4002-imx-gpcv2-wake-smccc.patch.patch" + ;; Does not apply, needs further investigation + ;; "imx8mq-mnt-reform2/v19_20241126_sandor_yu_initial_support_cadence_mhdp8501_hdmi_dp_for_i_mx8mq.mbx" + "ls1028a-mnt-reform2/0000-dtsi-add-hdptx.patch" + "meson-g12b-bananapi-cm4-mnt-pocket-reform/0001-a311d-viu-fifo-lines-config.patch" + "meson-g12b-bananapi-cm4-mnt-pocket-reform/0002-a311d-viu-fifo-lines-config-header.patch" + "meson-g12b-bananapi-cm4-mnt-pocket-reform/0003-tlv320aic31xx-add-1228800hz-support.patch" + "meson-g12b-bananapi-cm4-mnt-reform2/0001-Revert-drm-bridge-synopsys-dw-mipi-dsi-enable-EoTp-b.patch" + "meson-g12b-bananapi-cm4-mnt-reform2/0011-dw-mipi-dsi-phy-stop-wait-time.patch" + "meson-g12b-bananapi-cm4-mnt-reform2/0012-innolux-n125hce-gn1-timing-tweaks.patch" + "meson-g12b-bananapi-cm4-mnt-reform2/0013-meson-viu-hold-fifo-lines.patch" + "meson-g12b-bananapi-cm4-mnt-reform2/0014-meson-venc-sync.patch.patch" + "meson-g12b-bananapi-cm4-mnt-reform2/0015-meson-dw-mipi-dsi-sync-invert.patch" + "meson-g12b-bananapi-cm4-mnt-reform2/0016-sn65dsi86-burst-mode-support.patch" + "meson-g12b-bananapi-cm4-mnt-reform2/0018-sn65dsi86-never-turn-off.patch" + "meson-g12b-bananapi-cm4-mnt-reform2/0020-LOCAL-ALSA-Assign-internal-PCM-chmap-ELD-IEC958-kctl.patch" + "meson-g12b-bananapi-cm4-mnt-reform2/0021-HACK-of-partial-revert-of-fdt.c-changes.patch" + "meson-g12b-bananapi-cm4-mnt-reform2/0022-add-bt-and-eth-resets.patch" + "meson-g12b-bananapi-cm4-mnt-reform2/0023-sdio-pullups.patch" + "meson-g12b-bananapi-cm4-mnt-reform2/0024-sdio-improve-wifi-speed.patch" + "rk3588-mnt-reform2/0001-regulator-Add-of_regulator_get_optional-for-pure-DT-.patch" + "rk3588-mnt-reform2/0001-scripts-package-builddeb-allow-hooks-also-in-usr-sha.patch" + "rk3588-mnt-reform2/0002-regulator-Add-devres-version-of-of_regulator_get_opt.patch" + "rk3588-mnt-reform2/0004-arm64-dts-rockchip-rk3588-rock5b-add-USB-C-support.patch" + "rk3588-mnt-reform2/0005-math.h-add-DIV_ROUND_UP_NO_OVERFLOW.patch" + "rk3588-mnt-reform2/0006-clk-divider-Fix-divisor-masking-on-64-bit-platforms.patch" + "rk3588-mnt-reform2/0007-clk-composite-replace-open-coded-abs_diff.patch" + "rk3588-mnt-reform2/0008-clk-rockchip-support-clocks-registered-late.patch" + "rk3588-mnt-reform2/0009-clk-rockchip-rk3588-register-GATE_LINK-later.patch" + "rk3588-mnt-reform2/0010-clk-rockchip-expose-rockchip_clk_set_lookup.patch" + "rk3588-mnt-reform2/0011-clk-rockchip-implement-linked-gate-clock-support.patch" + "rk3588-mnt-reform2/0012-clk-rockchip-rk3588-drop-RK3588_LINKED_CLK.patch" + "rk3588-mnt-reform2/0013-arm64-dts-rockchip-rk3588-evb1-add-bluetooth-rfkill.patch" + "rk3588-mnt-reform2/0014-arm64-dts-rockchip-rk3588-evb1-improve-PCIe-ethernet.patch" + "rk3588-mnt-reform2/0015-arm64-dts-rockchip-Slow-down-EMMC-a-bit-to-keep-IO-s.patch" + "rk3588-mnt-reform2/0016-vop2-Add-clock-resets-support.patch" + "rk3588-mnt-reform2/0017-arm64-dts-rockchip-Add-VOP-clock-resets-for-rk3588s.patch" + "rk3588-mnt-reform2/0018-dt-bindings-display-vop2-Add-VP-clock-resets.patch" + "rk3588-mnt-reform2/0019-media-v4l2-ctrls-core-Set-frame_mbs_only_flag-by-def.patch" + "rk3588-mnt-reform2/0020-media-rockchip-Move-H264-CABAC-table-to-header-file.patch" + "rk3588-mnt-reform2/0021-media-rockchip-Introduce-the-rkvdec2-driver.patch" + "rk3588-mnt-reform2/0022-media-dt-bindings-rockchip-Document-RK3588-Video-Dec.patch" + "rk3588-mnt-reform2/0023-arm64-dts-rockchip-Add-rkvdec2-Video-Decoder-on-rk35.patch" + "rk3588-mnt-reform2/0024-arm64-defconfig-enable-Rockchip-RK3588-video-decoder.patch" + "rk3588-mnt-reform2/0025-mfd-rk8xx-Fix-shutdown-handler.patch" + "rk3588-mnt-reform2/0026-WIP-phy-phy-rockchip-samsung-hdptx-Add-FRL-EARC-supp.patch" + "rk3588-mnt-reform2/0027-TESTING-phy-phy-rockchip-samsung-hdptx-Add-verbose-l.patch" + "rk3588-mnt-reform2/0028-WIP-dt-bindings-display-rockchip-drm-Add-optional-cl.patch" + "rk3588-mnt-reform2/0029-WIP-drm-rockchip-vop2-Improve-display-modes-handling.patch" + "rk3588-mnt-reform2/0030-arm64-dts-rockchip-Add-HDMI0-bridge-to-rk3588.patch" + "rk3588-mnt-reform2/0031-arm64-dts-rockchip-Enable-HDMI0-on-rock-5b.patch" + "rk3588-mnt-reform2/0032-arm64-dts-rockchip-Enable-HDMI0-on-rk3588-evb1.patch" + "rk3588-mnt-reform2/0033-WIP-arm64-dts-rockchip-Enable-HDMI0-PHY-clk-provider.patch" + "rk3588-mnt-reform2/0034-WIP-arm64-dts-rockchip-Make-use-of-HDMI0-PHY-PLL-on-.patch" + "rk3588-mnt-reform2/0035-WIP-arm64-dts-rockchip-Make-use-of-HDMI0-PHY-PLL-on-.patch" + "rk3588-mnt-reform2/0036-dt-bindings-display-bridge-Add-schema-for-Synopsys-D.patch" + "rk3588-mnt-reform2/0037-dt-bindings-display-rockchip-Add-schema-for-RK3588-H.patch" + "rk3588-mnt-reform2/0038-drm-bridge-synopsys-Add-DW-HDMI-QP-TX-controller-dri.patch" + "rk3588-mnt-reform2/0039-drm-rockchip-Add-basic-RK3588-HDMI-output-support.patch" + "rk3588-mnt-reform2/0040-arm64-defconfig-Enable-Rockchip-extensions-for-Synop.patch" + "rk3588-mnt-reform2/0041-MAINTAINERS-Add-entry-for-Synopsys-DesignWare-HDMI-R.patch" + "rk3588-mnt-reform2/0042-dt-bindings-media-Document-bindings-for-HDMI-RX-Cont.patch" + "rk3588-mnt-reform2/0043-arm64-dts-rockchip-Add-device-tree-support-for-HDMI-.patch" + "rk3588-mnt-reform2/0044-media-platform-synopsys-Add-support-for-HDMI-input-d.patch" + "rk3588-mnt-reform2/0045-arm64-defconfig-Enable-Synopsys-HDMI-receiver.patch" + "rk3588-mnt-reform2/0046-arm64-dts-rockchip-Enable-HDMI-receiver-on-rock-5b.patch" + "rk3588-mnt-reform2/0047-arm64-dts-rockchip-Enable-HDMI-receiver-on-RK3588-EV.patch" + "rk3588-mnt-reform2/0048-arm64-defconfig-Enable-default-EDID-for-Synopsys-HDM.patch" + "rk3588-mnt-reform2/0049-regulator-Add-devm_-of_regulator_get.patch" + "rk3588-mnt-reform2/0050-pmdomain-rockchip-cleanup-mutex-handling-in-rockchip.patch" + "rk3588-mnt-reform2/0051-pmdomain-rockchip-forward-rockchip_do_pmu_set_power_.patch" + "rk3588-mnt-reform2/0052-pmdomain-rockchip-reduce-indentation-in-rockchip_pd_.patch" + "rk3588-mnt-reform2/0053-dt-bindings-power-rockchip-add-regulator-support.patch" + "rk3588-mnt-reform2/0054-pmdomain-rockchip-add-regulator-support.patch" + "rk3588-mnt-reform2/0055-arm64-dts-rockchip-Add-GPU-power-domain-regulator-de.patch" + "rk3588-mnt-reform2/0056-dt-bindings-net-wireless-brcm4329-fmac-add-pci14e4-4.patch" + "rk3588-mnt-reform2/0057-dt-bindings-net-wireless-brcm4329-fmac-add-clock-des.patch" + "rk3588-mnt-reform2/0058-wifi-brcmfmac-Add-optional-lpo-clock-enable-support.patch" + ;; does not apply cleanly due to DEBLOBBING + ;; "rk3588-mnt-reform2/0059-wifi-brcmfmac-add-flag-for-random-seed-during-firmwa.patch" + "rk3588-mnt-reform2/0060-arm64-dts-rockchip-rk3588-evb1-add-WLAN-controller.patch" + "rk3588-mnt-reform2/0061-arm64-dts-rockchip-add-and-enable-gpu-node-for-Radxa.patch" + "rk3588-mnt-reform2/0062-arm64-dts-rockchip-Enable-HDMI0-on-rock-5a.patch" + "rk3588-mnt-reform2/0100-rk3588-dtsi-add-hdmi1-controller.patch" + "rk3588-mnt-reform2/0102-drm-panthor-Actually-suspend-IRQs-in-the-unplug-path.patch" + "rk3588-mnt-reform2/3001-display-rockchip-add-schema-for-rk3588-hdmi-tx.patch" + "rk3588-mnt-reform2/4000-mnt-rk3588-dual-hdmi-qp-rockchip.patch" + "rk3588-mnt-reform2/4001-mnt-rk3588-dual-hdmi-vop2-pll.patch" + "rk3588-mnt-reform2/5001-rk3588-dsi2-driver.patch" + "rk3588-mnt-reform2/5002-rk3588-dsi-dts-nodes.patch" + "rk3588-mnt-reform2/5100-modernize-hdmi1-in-dtsi.patch" + "rk3588-mnt-reform2/5110-hdptx-crash-workaround.patch" + "rk3588-mnt-reform2/5200-drm-rockchip-Set-dma-mask-to-64-bit.patch")))) + ;; FIXME consolidate copy-*-dts-files phases + (add-after 'unpack 'copy-rockchip-dts-files + (lambda* (#:key inputs #:allow-other-keys) + (for-each (lambda (dts) + (copy-file + (search-input-file + inputs + (string-append "/dts/" dts)) + (string-append "arch/arm64/boot/dts/rockchip/" dts))) + (list + "rk3588-mnt-reform2.dts" + "rk3588-mnt-pocket-reform.dts" + "rk3588-mnt-reform-next.dts" + )))) + (add-after 'unpack 'copy-freescale-dts-files + (lambda* (#:key inputs #:allow-other-keys) + (for-each (lambda (dts) + (copy-file + (search-input-file + inputs + (string-append "/dts/" dts)) + (string-append "arch/arm64/boot/dts/freescale/" dts))) + (list + "fsl-ls1028a-mnt-reform2.dts" + "imx8mq-mnt-reform2-hdmi.dts" + "imx8mp-mnt-pocket-reform.dts" + "imx8mq-mnt-reform2.dts" + "imx8mp-mnt-reform2.dts" + )))) + (add-after 'unpack 'copy-amlogic-dts-files + (lambda* (#:key inputs #:allow-other-keys) + (for-each (lambda (dts) + (copy-file + (search-input-file + inputs + (string-append "/dts/" dts)) + (string-append "arch/arm64/boot/dts/amlogic/" dts))) + (list + "meson-g12b-bananapi-cm4-mnt-pocket-reform.dts" + "meson-g12b-bananapi-cm4-mnt-reform2.dts" + )))) + (add-after 'unpack 'adjust-makefiles-with-new-dtb + (lambda _ + (substitute* "arch/arm64/boot/dts/amlogic/Makefile" + (("meson-g12b-bananapi-cm4-mnt-reform2.dtb") + "meson-g12b-bananapi-cm4-mnt-reform2.dtb +dtb-$(CONFIG_ARCH_MESON) += meson-g12b-bananapi-cm4-mnt-pocket-reform.dtb")) + (substitute* "arch/arm64/boot/dts/freescale/Makefile" + (("fsl-ls1028a-rdb.dtb") + "fsl-ls1028a-rdb.dtb +dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-mnt-reform2.dtb")) + (substitute* "arch/arm64/boot/dts/freescale/Makefile" + (("imx8mq-mnt-reform2.dtb") + "imx8mq-mnt-reform2.dtb +dtb-$(CONFIG_ARCH_MXC) += imx8mp-mnt-reform2.dtb +dtb-$(CONFIG_ARCH_MXC) += imx8mp-mnt-pocket-reform.dtb +dtb-$(CONFIG_ARCH_MXC) += imx8mq-mnt-reform2-hdmi.dtb")) + (substitute* "arch/arm64/boot/dts/rockchip/Makefile" + (("rk3588-rock-5b.dtb") + "rk3588-rock-5b.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-mnt-reform2.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-mnt-reform-next.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-mnt-pocket-reform.dtb"))))))))))) (define-public linux-libre-riscv64-generic (make-linux-libre* linux-libre-version diff --git a/gnu/packages/patches/reform/dts.patch b/gnu/packages/patches/reform/dts.patch deleted file mode 100644 index 497ac15598..0000000000 --- a/gnu/packages/patches/reform/dts.patch +++ /dev/null @@ -1,7485 +0,0 @@ -Index: linux/arch/arm64/boot/dts/amlogic/Makefile -=================================================================== ---- linux.orig/arch/arm64/boot/dts/amlogic/Makefile -+++ linux/arch/arm64/boot/dts/amlogic/Makefile -@@ -22,6 +22,7 @@ dtb-$(CONFIG_ARCH_MESON) += meson-g12b-a - dtb-$(CONFIG_ARCH_MESON) += meson-g12b-a311d-khadas-vim3-ts050.dtb - dtb-$(CONFIG_ARCH_MESON) += meson-g12b-bananapi-cm4-cm4io.dtb - dtb-$(CONFIG_ARCH_MESON) += meson-g12b-bananapi-cm4-mnt-reform2.dtb -+dtb-$(CONFIG_ARCH_MESON) += meson-g12b-bananapi-cm4-mnt-pocket-reform.dtb - dtb-$(CONFIG_ARCH_MESON) += meson-g12b-dreambox-one.dtb - dtb-$(CONFIG_ARCH_MESON) += meson-g12b-dreambox-two.dtb - dtb-$(CONFIG_ARCH_MESON) += meson-g12b-gsking-x.dtb -Index: linux/arch/arm64/boot/dts/amlogic/meson-g12b-bananapi-cm4-mnt-pocket-reform.dts -=================================================================== ---- /dev/null -+++ linux/arch/arm64/boot/dts/amlogic/meson-g12b-bananapi-cm4-mnt-pocket-reform.dts -@@ -0,0 +1,378 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Copyright (c) 2023 Neil Armstrong <neil.armstrong@linaro.org> -+ * Copyright 2023 MNT Research GmbH -+ */ -+ -+/dts-v1/; -+ -+#include "meson-g12b-bananapi-cm4.dtsi" -+#include <dt-bindings/input/input.h> -+#include <dt-bindings/leds/common.h> -+#include <dt-bindings/sound/meson-g12a-tohdmitx.h> -+ -+/ { -+ model = "MNT Pocket Reform with BPI-CM4 Module"; -+ compatible = "mntre,reform2-cm4", "bananapi,bpi-cm4", "amlogic,a311d", "amlogic,g12b"; -+ chassis-type = "laptop"; -+ -+ aliases { -+ ethernet0 = ðmac; -+ i2c0 = &i2c1; -+ i2c1 = &i2c3; -+ }; -+ -+ hdmi_connector: hdmi-connector { -+ compatible = "hdmi-connector"; -+ type = "a"; -+ -+ port { -+ hdmi_connector_in: endpoint { -+ remote-endpoint = <&hdmi_tx_tmds_out>; -+ }; -+ }; -+ }; -+ -+ leds { -+ compatible = "gpio-leds"; -+ -+ led-blue { -+ color = <LED_COLOR_ID_BLUE>; -+ function = LED_FUNCTION_STATUS; -+ gpios = <&gpio_ao GPIOAO_7 GPIO_ACTIVE_HIGH>; -+ linux,default-trigger = "heartbeat"; -+ }; -+ -+ led-green { -+ color = <LED_COLOR_ID_GREEN>; -+ function = LED_FUNCTION_STATUS; -+ gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_HIGH>; -+ }; -+ }; -+ -+ sound { -+ compatible = "amlogic,axg-sound-card"; -+ model = "MNT-POCKET-REFORM-BPI-CM4"; -+ audio-widgets = "Headphone", "Headphone Jack", -+ "Speaker", "Speaker", -+ "Microphone", "Microphone Jack"; -+ audio-aux-devs = <&tdmout_a>, <&tdmout_b>, <&tdmin_b>; -+ audio-routing = "TDMOUT_A IN 0", "FRDDR_A OUT 0", -+ "TDMOUT_A IN 1", "FRDDR_B OUT 0", -+ "TDMOUT_A IN 2", "FRDDR_C OUT 0", -+ "TDM_A Playback", "TDMOUT_A OUT", -+ "TDMOUT_B IN 0", "FRDDR_A OUT 1", -+ "TDMOUT_B IN 1", "FRDDR_B OUT 1", -+ "TDMOUT_B IN 2", "FRDDR_C OUT 1", -+ "TDM_B Playback", "TDMOUT_B OUT", -+ "TDMIN_B IN 1", "TDM_B Capture", -+ "TDMIN_B IN 4", "TDM_B Loopback", -+ "TODDR_A IN 1", "TDMIN_B OUT", -+ "TODDR_B IN 1", "TDMIN_B OUT", -+ "TODDR_C IN 1", "TDMIN_B OUT", -+ "MIC1RP", "MICBIAS", -+ "MIC1RP", "Microphone Jack", -+ "Headphone Jack", "HPR", -+ "Speaker", "SPK"; -+ -+ assigned-clocks = <&clkc CLKID_MPLL2>, -+ <&clkc CLKID_MPLL0>, -+ <&clkc CLKID_MPLL1>; -+ assigned-clock-parents = <0>, <0>, <0>; -+ assigned-clock-rates = <294912000>, -+ <270950400>, -+ <393216000>; -+ -+ dai-link-0 { -+ sound-dai = <&frddr_a>; -+ }; -+ -+ dai-link-1 { -+ sound-dai = <&frddr_b>; -+ }; -+ -+ dai-link-2 { -+ sound-dai = <&frddr_c>; -+ }; -+ -+ dai-link-3 { -+ sound-dai = <&toddr_a>; -+ }; -+ -+ dai-link-4 { -+ sound-dai = <&toddr_b>; -+ }; -+ -+ dai-link-5 { -+ sound-dai = <&toddr_c>; -+ }; -+ -+ /* 8ch hdmi interface */ -+ dai-link-6 { -+ sound-dai = <&tdmif_a>; -+ dai-format = "i2s"; -+ dai-tdm-slot-tx-mask-0 = <1 1>; -+ dai-tdm-slot-tx-mask-1 = <1 1>; -+ dai-tdm-slot-tx-mask-2 = <1 1>; -+ dai-tdm-slot-tx-mask-3 = <1 1>; -+ mclk-fs = <256>; -+ -+ codec { -+ sound-dai = <&tohdmitx TOHDMITX_I2S_IN_A>; -+ }; -+ }; -+ -+ /* Analog Audio */ -+ dai-link-7 { -+ sound-dai = <&tdmif_b>; -+ dai-format = "i2s"; -+ dai-tdm-slot-tx-mask-0 = <1 1>; -+ mclk-fs = <256>; -+ -+ codec { -+ sound-dai = <&tlv320aic3100>; -+ }; -+ }; -+ -+ /* hdmi glue */ -+ dai-link-8 { -+ sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>; -+ -+ codec { -+ sound-dai = <&hdmi_tx>; -+ }; -+ }; -+ }; -+ -+ reg_main_1v8: regulator-main-1v8 { -+ compatible = "regulator-fixed"; -+ regulator-name = "1V8"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ vin-supply = <®_main_3v3>; -+ }; -+ -+ reg_main_1v2: regulator-main-1v2 { -+ compatible = "regulator-fixed"; -+ regulator-name = "1V2"; -+ regulator-min-microvolt = <1200000>; -+ regulator-max-microvolt = <1200000>; -+ vin-supply = <®_main_5v>; -+ }; -+ -+ reg_main_3v3: regulator-main-3v3 { -+ compatible = "regulator-fixed"; -+ regulator-name = "3V3"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ }; -+ -+ reg_main_5v: regulator-main-5v { -+ compatible = "regulator-fixed"; -+ regulator-name = "5V"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ }; -+ -+ reg_main_usb: regulator-main-usb { -+ compatible = "regulator-fixed"; -+ regulator-name = "USB_PWR"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ vin-supply = <®_main_5v>; -+ }; -+ -+ clock_12288: clock_12288 { -+ compatible = "fixed-clock"; -+ #clock-cells = <0>; -+ clock-frequency = <12288000>; -+ }; -+ -+ spi { -+ compatible = "spi-gpio"; -+ #address-cells = <0x1>; -+ ranges; -+ -+ sck-gpios = <&gpio_ao GPIOAO_5 0>; // GPIOAO_5 / GPIO7 -+ miso-gpios = <&gpio GPIOH_4 0>; // GPIOH_4 / GPIO5 -+ mosi-gpios = <&gpio_ao GPIOAO_10 0>; // GPIOAO_10 / GPIO6 -+ cs-gpios = <&gpio GPIOA_10 0>; // GPIOA_10 / GPIO4 -+ num-chipselects = <1>; -+ -+ spidev@0 { -+ compatible = "mntre,lpc11u24"; -+ spi-max-frequency = <1000000>; -+ reg = <0>; -+ }; -+ }; -+}; -+ -+&mipi_analog_dphy { -+ status = "okay"; -+}; -+ -+&mipi_dphy { -+ status = "okay"; -+}; -+ -+&mipi_dsi { -+ status = "okay"; -+ -+ assigned-clocks = <&clkc CLKID_GP0_PLL>, -+ <&clkc CLKID_MIPI_DSI_PXCLK_SEL>, -+ <&clkc CLKID_MIPI_DSI_PXCLK>, -+ <&clkc CLKID_CTS_ENCL_SEL>, -+ <&clkc CLKID_VCLK2_SEL>; -+ assigned-clock-parents = <0>, -+ <&clkc CLKID_GP0_PLL>, -+ <0>, -+ <&clkc CLKID_VCLK2_DIV1>, -+ <&clkc CLKID_GP0_PLL>; -+ assigned-clock-rates = <840000000>, -+ <0>, -+ <840000000>, -+ <0>, -+ <0>; -+ -+ panel@0 { -+ compatible = "jdi,lt070me05000"; -+ reg = <0>; -+ -+ // reset is driven by rp2040 -+ // dcdc en is also driven by rp2040 -+ enable-gpios = <&gpio 58 GPIO_ACTIVE_HIGH>; -+ -+ // on A311D, we shift the vsync by one line to counteract VIU_OSD_HOLD_FIFO_LINES -+ // (which can't be less than 1) -+ vsync-shift = <1>; -+ probe-mode-lpm; -+ -+ port { -+ panel_in: endpoint { -+ remote-endpoint = <&mipi_dsi_out>; -+ }; -+ }; -+ }; -+}; -+ -+&mipi_dsi_panel_port { -+ mipi_dsi_out: endpoint { -+ remote-endpoint = <&panel_in>; -+ }; -+}; -+ -+&vpu { -+ // on A311D, we currently have to set VIU_OSD_HOLD_FIFO_LINES to the lowest -+ // possible value or get a vertically shifted image -+ viu-hold-fifo-lines = <0>; -+}; -+ -+&cecb_AO { -+ status = "okay"; -+}; -+ -+ðmac { -+ status = "okay"; -+}; -+ -+&hdmi_tx { -+ status = "okay"; -+}; -+ -+&hdmi_tx_tmds_port { -+ hdmi_tx_tmds_out: endpoint { -+ remote-endpoint = <&hdmi_connector_in>; -+ }; -+}; -+ -+&pwm_AO_ab { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pwm_ao_a_pins>; -+ status = "okay"; -+}; -+ -+&i2c0 { -+ status = "okay"; -+}; -+ -+&i2c2 { -+ status = "okay"; -+}; -+ -+&i2c3 { -+ status = "okay"; -+ -+ tlv320aic3100: codec@18 { -+ compatible = "ti,tlv320aic3100"; -+ reg = <0x18>; -+ clocks = <&clock_12288>; -+ clock-names = "mclk"; -+ ai31xx-micbias-vg = <2>; -+ #sound-dai-cells = <0>; -+ -+ HPVDD-supply = <®_main_3v3>; -+ SPRVDD-supply = <®_main_5v>; -+ SPLVDD-supply = <®_main_5v>; -+ AVDD-supply = <®_main_3v3>; -+ IOVDD-supply = <®_main_3v3>; -+ DVDD-supply = <®_main_1v8>; -+ }; -+ -+ rtc@68 { -+ compatible = "nxp,pcf8523"; -+ reg = <0x68>; -+ }; -+}; -+ -+&pcie { -+ status = "okay"; -+}; -+ -+&sd_emmc_b { -+ status = "okay"; -+}; -+ -+&tdmif_a { -+ status = "okay"; -+}; -+ -+&tdmout_a { -+ status = "okay"; -+}; -+ -+&tdmif_b { -+ pinctrl-0 = <&tdm_b_dout0_pins>, <&tdm_b_fs_pins>, <&tdm_b_sclk_pins>, <&tdm_b_din1_pins>; -+ pinctrl-names = "default"; -+ -+ assigned-clocks = <&clkc_audio AUD_CLKID_TDM_SCLK_PAD1>, -+ <&clkc_audio AUD_CLKID_TDM_LRCLK_PAD1>; -+ assigned-clock-parents = <&clkc_audio AUD_CLKID_MST_B_SCLK>, -+ <&clkc_audio AUD_CLKID_MST_B_LRCLK>; -+ assigned-clock-rates = <0>, <0>; -+}; -+ -+&tdmin_b { -+ status = "okay"; -+}; -+ -+&toddr_a { -+ status = "okay"; -+}; -+ -+&toddr_b { -+ status = "okay"; -+}; -+ -+&toddr_c { -+ status = "okay"; -+}; -+ -+&tohdmitx { -+ status = "okay"; -+}; -+ -+&usb { -+ dr_mode = "host"; -+ -+ status = "okay"; -+}; -Index: linux/arch/arm64/boot/dts/freescale/Makefile -=================================================================== ---- linux.orig/arch/arm64/boot/dts/freescale/Makefile -+++ linux/arch/arm64/boot/dts/freescale/Makefile -@@ -14,6 +14,7 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1 - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-kontron-sl28-var4.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-rdb.dtb -+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-mnt-reform2.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-qds.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-rdb.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-tqmls1043a-mbls10xxa.dtb -@@ -213,6 +214,9 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mq-librem5 - dtb-$(CONFIG_ARCH_MXC) += imx8mq-librem5-r4.dtb - dtb-$(CONFIG_ARCH_MXC) += imx8mq-tqma8mq-mba8mx.dtb - dtb-$(CONFIG_ARCH_MXC) += imx8mq-mnt-reform2.dtb -+dtb-$(CONFIG_ARCH_MXC) += imx8mp-mnt-reform2.dtb -+dtb-$(CONFIG_ARCH_MXC) += imx8mp-mnt-pocket-reform.dtb -+dtb-$(CONFIG_ARCH_MXC) += imx8mq-mnt-reform2-hdmi.dtb - dtb-$(CONFIG_ARCH_MXC) += imx8mq-nitrogen.dtb - dtb-$(CONFIG_ARCH_MXC) += imx8mq-phanbell.dtb - dtb-$(CONFIG_ARCH_MXC) += imx8mq-pico-pi.dtb -Index: linux/arch/arm64/boot/dts/freescale/fsl-ls1028a-mnt-reform2.dts -=================================================================== ---- /dev/null -+++ linux/arch/arm64/boot/dts/freescale/fsl-ls1028a-mnt-reform2.dts -@@ -0,0 +1,203 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Device Tree file for MNT Reform 2 with RBZ LS1028A SOM. -+ * -+ * Copyright 2022 MNT Research GmbH -+ * -+ * Lukas F. Hartmann <lukas@mntre.com> -+ * -+ */ -+ -+/dts-v1/; -+#include "fsl-ls1028a.dtsi" -+ -+#include <dt-bindings/gpio/gpio.h> -+ -+/ { -+ model = "MNT Reform 2 with LS1028A Module"; -+ compatible = "fsl,ls1028a-rdb", "fsl,ls1028a"; -+ -+ aliases { -+ crypto = &crypto; -+ serial0 = &duart0; -+ serial1 = &duart1; -+ serial2 = &lpuart1; -+ mmc0 = &esdhc; -+ mmc1 = &esdhc1; -+ rtc1 = &ftm_alarm0; -+ }; -+ -+ chosen { -+ stdout-path = "serial0:115200n8"; -+ }; -+ -+ memory@80000000 { -+ device_type = "memory"; -+ reg = <0x0 0x80000000 0x1 0x0000000>; -+ }; -+ -+ sys_mclk: clock-mclk { -+ compatible = "fixed-clock"; -+ #clock-cells = <0>; -+ clock-frequency = <12000000>; -+ }; -+ -+ reg_1p8v: regulator-1p8v { -+ compatible = "regulator-fixed"; -+ regulator-name = "1P8V"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+ }; -+ -+ sb_3v3: regulator-sb3v3 { -+ compatible = "regulator-fixed"; -+ regulator-name = "3v3_vbus"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ sound { -+ compatible = "fsl,imx-audio-wm8960"; -+ model = "wm8960-audio"; -+ audio-cpu = <&sai4>; -+ audio-codec = <&wm8960>; -+ -+ audio-routing = -+ "Headphone Jack", "HP_L", -+ "Headphone Jack", "HP_R", -+ "Ext Spk", "SPK_LP", -+ "Ext Spk", "SPK_LN", -+ "Ext Spk", "SPK_RP", -+ "Ext Spk", "SPK_RN", -+ "LINPUT1", "Mic Jack", -+ "Mic Jack", "MICB", -+ "LINPUT2", "Line In Jack", -+ "RINPUT2", "Line In Jack"; -+ }; -+ -+ backlight: backlight { -+ compatible = "pwm-backlight"; -+ pwms = <&pwm0 1 10000 0>; -+ brightness-levels = <0 8 16 32 64 128 160 200 255>; -+ default-brightness-level = <8>; -+ enable-gpios = <&gpio1 24 GPIO_ACTIVE_HIGH>; -+ }; -+}; -+ -+&dpclk { -+ // DP VCO clock is eDP pixel clock (162MHz) divided by 1.25 -+ fsl,vco-hz = <1296000000>; -+}; -+ -+&duart0 { -+ status = "okay"; -+}; -+ -+&duart1 { -+ status = "okay"; -+}; -+ -+// connected to LPC11U24 chip on the motherboard -+&lpuart1 { -+ status = "okay"; -+}; -+ -+&esdhc { -+ sd-uhs-sdr50; -+ sd-uhs-sdr25; -+ sd-uhs-sdr12; -+ bus-width = <1>; -+ status = "okay"; -+}; -+ -+&esdhc1 { -+ mmc-hs200-1_8v; -+ bus-width = <8>; -+ status = "okay"; -+}; -+ -+&fspi { -+ status = "disabled"; -+}; -+ -+&i2c0 { -+ status = "okay"; -+ -+ // Audio chip on motherboard -+ wm8960: codec@1a { -+ #sound-dai-cells = <0>; -+ compatible = "wlf,wm8960"; -+ reg = <0x1a>; -+ clocks = <&sys_mclk>; -+ clock-names = "mclk"; -+ }; -+ -+ // Realtime clock chip on motherboard -+ pcf8523: pcf8523@68 { -+ compatible = "nxp,pcf8523"; -+ reg = <0x68>; -+ }; -+}; -+ -+&enetc_port0 { -+ phy-handle = <&sgmii_phy0>; -+ phy-connection-type = "sgmii"; -+ managed = "in-band-status"; -+ status = "okay"; -+}; -+ -+&enetc_mdio_pf3 { -+ sgmii_phy0: ethernet-phy@0 { -+ reg = <0x0>; -+ }; -+}; -+ -+/* -+XSPI1_A_DATA4 = GPIO2_DAT28 -+XSPI1_A_DATA5 = GPIO2_DAT29 -+XSPI1_A_DATA6 = GPIO2_DAT30 -+*/ -+ -+&pcie1 { -+ status = "okay"; -+}; -+ -+&pcie2 { -+ status = "okay"; -+}; -+ -+&pwm0 { -+ status = "okay"; -+}; -+ -+&sata { -+ status = "okay"; -+ dma-coherent; -+}; -+ -+&sai4 { -+ fsl,sai-mclk-direction-output; -+ status = "okay"; -+}; -+ -+&usb0 { -+ dr_mode = "host"; -+ status = "okay"; -+}; -+ -+&usb1 { -+ dr_mode = "host"; -+ status = "okay"; -+}; -+ -+&dspi2 { -+ status = "okay"; -+ spidev@0 { -+ compatible = "mntre,lpc11u24"; -+ spi-max-frequency = <1000000>; -+ reg = <0>; -+ }; -+}; -Index: linux/arch/arm64/boot/dts/freescale/imx8mp-mnt-pocket-reform.dts -=================================================================== ---- /dev/null -+++ linux/arch/arm64/boot/dts/freescale/imx8mp-mnt-pocket-reform.dts -@@ -0,0 +1,984 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+ -+/* -+ * Copyright 2019-2022 MNT Research GmbH -+ * Copyright 2021 Lucas Stach <dev@lynxeye.de> -+ * Copyright 2020 Boundary Devices -+*/ -+ -+// https://github.com/boundarydevices/linux/blob/boundary-imx_5.15.y/arch/arm64/boot/dts/freescale/imx8mp-nitrogen8mp.dts -+ -+/dts-v1/; -+ -+#include <dt-bindings/phy/phy-imx8-pcie.h> -+#include "imx8mp.dtsi" -+ -+&iomuxc { -+ pinctrl_eqos: eqosgrp { -+ fsl,pins = < -+ MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC 0x20 -+ MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO 0xa0 -+ MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x1f -+ MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x1f -+ MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0 0x1f -+ MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1 0x1f -+ MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2 0x1f -+ MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3 0x1f -+ -+ MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x91 -+ MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK 0x91 -+ MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0 0x91 -+ MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1 0x91 -+ MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2 0x91 -+ MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3 0x91 -+#define GP_EQOS_RESET <&gpio3 16 GPIO_ACTIVE_LOW> -+ MX8MP_IOMUXC_NAND_READY_B__GPIO3_IO16 0x100 -+#define GPIRQ_EQOS_PHY <&gpio3 14 IRQ_TYPE_LEVEL_LOW> -+ MX8MP_IOMUXC_NAND_DQS__GPIO3_IO14 0x10 -+ >; -+ }; -+ -+ pinctrl_hog: hoggrp { -+ fsl,pins = < -+ //MX8MP_IOMUXC_NAND_DATA01__GPIO3_IO07 0x119 /* J31 */ -+ MX8MP_IOMUXC_SPDIF_RX__GPIO5_IO04 0x41 /* Pin 17 */ -+ MX8MP_IOMUXC_SPDIF_EXT_CLK__GPIO5_IO05 0x41 /* Pin 19 */ -+ MX8MP_IOMUXC_SPDIF_TX__GPIO5_IO03 0x41 /* Pin 21 */ -+ MX8MP_IOMUXC_SD1_RESET_B__GPIO2_IO10 0x41 /* Pin 23 */ -+ MX8MP_IOMUXC_SD1_DATA6__GPIO2_IO08 0x41 /* Pin 25 */ -+ MX8MP_IOMUXC_SD1_DATA5__GPIO2_IO07 0x41 /* Pin 29 */ -+ //MX8MP_IOMUXC_SD1_DATA4__GPIO2_IO06 0x41 /* Pin 31 */ -+ MX8MP_IOMUXC_SAI1_MCLK__GPIO4_IO20 0x16 /* Pin 2 */ -+ MX8MP_IOMUXC_SAI1_TXD7__GPIO4_IO19 0x1c4 /* Pin 4 */ -+ >; -+ }; -+ -+ pinctrl_panel: panelgrp { -+ fsl,pins = < -+ MX8MP_IOMUXC_GPIO1_IO06__GPIO1_IO06 0x140 -+ MX8MP_IOMUXC_GPIO1_IO07__GPIO1_IO07 0x140 -+ MX8MP_IOMUXC_SD1_DATA4__GPIO2_IO06 0x41 /* Pin 31 */ -+ >; -+ }; -+ -+ pinctrl_hdmi: hdmigrp { -+ fsl,pins = < -+ MX8MP_IOMUXC_HDMI_DDC_SCL__HDMIMIX_HDMI_SCL 0x1c3 -+ MX8MP_IOMUXC_HDMI_DDC_SDA__HDMIMIX_HDMI_SDA 0x1c3 -+ MX8MP_IOMUXC_HDMI_HPD__HDMIMIX_HDMI_HPD 0x19 -+ MX8MP_IOMUXC_HDMI_CEC__HDMIMIX_HDMI_CEC 0x19 -+ -+ /*MX8MP_IOMUXC_HDMI_DDC_SCL__HDMIMIX_HDMI_SCL 0x400001c3 -+ MX8MP_IOMUXC_HDMI_DDC_SDA__HDMIMIX_HDMI_SDA 0x400001c3 -+ MX8MP_IOMUXC_HDMI_HPD__HDMIMIX_HDMI_HPD 0x40000019 -+ MX8MP_IOMUXC_HDMI_CEC__HDMIMIX_HDMI_CEC 0x40000019*/ -+ >; -+ }; -+ -+ pinctrl_bt_rfkill: bt-rfkillgrp { -+ fsl,pins = < -+#define GP_BT_RFKILL_RESET <&gpio3 9 GPIO_ACTIVE_LOW> -+ MX8MP_IOMUXC_NAND_DATA03__GPIO3_IO09 0x119 -+ >; -+ }; -+ -+ pinctrl_ecspi2: ecspi2grp { -+ fsl,pins = < -+ /* J31 */ -+ MX8MP_IOMUXC_ECSPI2_SCLK__ECSPI2_SCLK 0x82 /* Pin 20 */ -+ MX8MP_IOMUXC_ECSPI2_MOSI__ECSPI2_MOSI 0x82 /* Pin 10 */ -+ MX8MP_IOMUXC_ECSPI2_MISO__ECSPI2_MISO 0x82 /* Pin 8 */ -+#define GP_ECSPI2_CS <&gpio5 13 GPIO_ACTIVE_LOW> -+ MX8MP_IOMUXC_ECSPI2_SS0__GPIO5_IO13 0x143 /* Pin 6 */ -+ >; -+ }; -+ -+ pinctrl_i2c1: i2c1grp { -+ fsl,pins = < -+ MX8MP_IOMUXC_I2C1_SCL__I2C1_SCL 0x400001c3 -+ MX8MP_IOMUXC_I2C1_SDA__I2C1_SDA 0x400001c3 -+ >; -+ }; -+ -+ pinctrl_i2c1_1: i2c1-1grp { -+ fsl,pins = < -+#define GP_I2C1_SCL <&gpio5 14 GPIO_OPEN_DRAIN> -+ MX8MP_IOMUXC_I2C1_SCL__GPIO5_IO14 0x1c3 -+#define GP_I2C1_SDA <&gpio5 15 GPIO_OPEN_DRAIN> -+ MX8MP_IOMUXC_I2C1_SDA__GPIO5_IO15 0x1c3 -+ >; -+ }; -+ -+ pinctrl_i2c2: i2c2grp { -+ fsl,pins = < -+ MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL 0x400001c3 -+ MX8MP_IOMUXC_I2C2_SDA__I2C2_SDA 0x400001c3 -+ >; -+ }; -+ -+ pinctrl_i2c2_1: i2c2-1grp { -+ fsl,pins = < -+#define GP_I2C2_SCL <&gpio5 16 GPIO_OPEN_DRAIN> -+ MX8MP_IOMUXC_I2C2_SCL__GPIO5_IO16 0x1c3 -+#define GP_I2C2_SDA <&gpio5 17 GPIO_OPEN_DRAIN> -+ MX8MP_IOMUXC_I2C2_SDA__GPIO5_IO17 0x1c3 -+ >; -+ }; -+ -+ pinctrl_i2c3: i2c3grp { -+ fsl,pins = < -+ MX8MP_IOMUXC_I2C3_SCL__I2C3_SCL 0x400001c3 -+ MX8MP_IOMUXC_I2C3_SDA__I2C3_SDA 0x400001c3 -+ >; -+ }; -+ -+ pinctrl_i2c3_1: i2c3-1grp { -+ fsl,pins = < -+#define GP_I2C3_SCL <&gpio5 18 GPIO_OPEN_DRAIN> -+ MX8MP_IOMUXC_I2C3_SCL__GPIO5_IO18 0x1c3 -+#define GP_I2C3_SDA <&gpio5 19 GPIO_OPEN_DRAIN> -+ MX8MP_IOMUXC_I2C3_SDA__GPIO5_IO19 0x1c3 -+ >; -+ }; -+ -+ pinctrl_i2c4: i2c4grp { -+ fsl,pins = < -+ MX8MP_IOMUXC_I2C4_SCL__I2C4_SCL 0x400001c3 -+ MX8MP_IOMUXC_I2C4_SDA__I2C4_SDA 0x400001c3 -+ >; -+ }; -+ -+ pinctrl_i2c4_1: i2c4-1grp { -+ fsl,pins = < -+#define GP_I2C4_SCL <&gpio5 20 GPIO_OPEN_DRAIN> -+ MX8MP_IOMUXC_I2C4_SCL__GPIO5_IO20 0x1c3 -+#define GP_I2C4_SDA <&gpio5 21 GPIO_OPEN_DRAIN> -+ MX8MP_IOMUXC_I2C4_SDA__GPIO5_IO21 0x1c3 -+ >; -+ }; -+ -+ pinctrl_reg_wlan_vmmc: reg-wlan-vmmcgrp { -+ fsl,pins = < -+#define GP_REG_WLAN_VMMC <&gpio2 19 GPIO_ACTIVE_HIGH> -+ MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19 0x16 -+ >; -+ }; -+ -+ pinctrl_sai2: sai2grp { -+ fsl,pins = < -+ MX8MP_IOMUXC_SAI2_TXFS__AUDIOMIX_SAI2_TX_SYNC 0xd6 -+ MX8MP_IOMUXC_SAI2_RXFS__AUDIOMIX_SAI2_RX_SYNC 0xd6 -+ MX8MP_IOMUXC_SAI2_TXC__AUDIOMIX_SAI2_TX_BCLK 0xd6 -+ MX8MP_IOMUXC_SAI2_RXC__AUDIOMIX_SAI2_RX_BCLK 0xd6 -+ MX8MP_IOMUXC_SAI2_RXD0__AUDIOMIX_SAI2_RX_DATA00 0xd6 -+ MX8MP_IOMUXC_SAI2_TXD0__AUDIOMIX_SAI2_TX_DATA00 0xd6 -+ MX8MP_IOMUXC_SAI2_MCLK__AUDIOMIX_SAI2_MCLK 0xd6 -+ >; -+ }; -+ -+ pinctrl_sai3: sai3grp { -+ fsl,pins = < -+ MX8MP_IOMUXC_SAI3_TXFS__AUDIOMIX_SAI3_TX_SYNC 0xd6 -+ MX8MP_IOMUXC_SAI3_RXFS__AUDIOMIX_SAI3_RX_SYNC 0xd6 -+ MX8MP_IOMUXC_SAI3_TXC__AUDIOMIX_SAI3_TX_BCLK 0xd6 -+ MX8MP_IOMUXC_SAI3_RXC__AUDIOMIX_SAI3_RX_BCLK 0xd6 -+ MX8MP_IOMUXC_SAI3_RXD__AUDIOMIX_SAI3_RX_DATA00 0xd6 -+ MX8MP_IOMUXC_SAI3_TXD__AUDIOMIX_SAI3_TX_DATA00 0xd6 -+ MX8MP_IOMUXC_SAI3_MCLK__AUDIOMIX_SAI3_MCLK 0xd6 -+ >; -+ }; -+ -+ pinctrl_pcie: pciegrp { -+ fsl,pins = < -+#define GP_PCIE_RESET <&gpio1 11 GPIO_ACTIVE_LOW> -+ MX8MP_IOMUXC_GPIO1_IO11__GPIO1_IO11 0x41 -+/*#define GP_PCIE_DISABLE <&gpio4 26 GPIO_ACTIVE_LOW> -+ MX8MP_IOMUXC_SAI2_TXD0__GPIO4_IO26 0x41*/ -+ >; -+ }; -+ -+ pinctrl_pmic: pmicirq { -+ fsl,pins = < -+#define GPIRQ_PMIC <&gpio3 0 IRQ_TYPE_LEVEL_LOW> -+ MX8MP_IOMUXC_NAND_ALE__GPIO3_IO00 0x41 -+ >; -+ }; -+ -+ pinctrl_edp_bridge: edpbridgegrp { -+ fsl,pins = < -+ MX8MP_IOMUXC_GPIO1_IO04__GPIO1_IO04 0x100 -+ >; -+ }; -+ -+ pinctrl_uart1: uart1grp { -+ fsl,pins = < -+ MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX 0x140 -+ MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX 0x140 -+ MX8MP_IOMUXC_UART3_RXD__UART1_DCE_CTS 0x140 -+ MX8MP_IOMUXC_UART3_TXD__UART1_DCE_RTS 0x140 -+#define GP_BT_ENABLE <&gpio3 9 GPIO_ACTIVE_HIGH> -+ MX8MP_IOMUXC_NAND_DATA03__GPIO3_IO09 0x119 -+ >; -+ }; -+ -+ pinctrl_uart2: uart2grp { -+ fsl,pins = < -+ MX8MP_IOMUXC_UART2_RXD__UART2_DCE_RX 0x140 -+ MX8MP_IOMUXC_UART2_TXD__UART2_DCE_TX 0x140 -+ >; -+ }; -+ -+ pinctrl_uart3: uart3grp { -+ fsl,pins = < -+ MX8MP_IOMUXC_ECSPI1_SCLK__UART3_DCE_RX 0x140 -+ MX8MP_IOMUXC_ECSPI1_MOSI__UART3_DCE_TX 0x140 -+ >; -+ }; -+ -+ pinctrl_uart4: uart4grp { -+ fsl,pins = < -+ MX8MP_IOMUXC_UART4_RXD__UART4_DCE_RX 0x140 -+ MX8MP_IOMUXC_UART4_TXD__UART4_DCE_TX 0x140 -+ >; -+ }; -+ -+ pinctrl_usb1_vbus: usb1grp { -+ fsl,pins = < -+ MX8MP_IOMUXC_GPIO1_IO14__USB2_OTG_PWR 0x10 -+ >; -+ }; -+ -+ pinctrl_usdhc1: usdhc1grp { -+ fsl,pins = < -+ MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK 0x190 -+ MX8MP_IOMUXC_SD1_CMD__USDHC1_CMD 0x1d0 -+ MX8MP_IOMUXC_SD1_DATA0__USDHC1_DATA0 0x1d0 -+ MX8MP_IOMUXC_SD1_DATA1__USDHC1_DATA1 0x1d0 -+ MX8MP_IOMUXC_SD1_DATA2__USDHC1_DATA2 0x1d0 -+ MX8MP_IOMUXC_SD1_DATA3__USDHC1_DATA3 0x1d0 -+ //MX8MP_IOMUXC_GPIO1_IO03__USDHC1_VSELECT 0x116 -+ >; -+ }; -+ -+ pinctrl_usdhc1_100mhz: usdhc1grp-100mhz { -+ fsl,pins = < -+ MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK 0x194 -+ MX8MP_IOMUXC_SD1_CMD__USDHC1_CMD 0x1d4 -+ MX8MP_IOMUXC_SD1_DATA0__USDHC1_DATA0 0x1d4 -+ MX8MP_IOMUXC_SD1_DATA1__USDHC1_DATA1 0x1d4 -+ MX8MP_IOMUXC_SD1_DATA2__USDHC1_DATA2 0x1d4 -+ MX8MP_IOMUXC_SD1_DATA3__USDHC1_DATA3 0x1d4 -+ >; -+ }; -+ -+ pinctrl_usdhc1_200mhz: usdhc1grp-200mhz { -+ fsl,pins = < -+ MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK 0x196 -+ MX8MP_IOMUXC_SD1_CMD__USDHC1_CMD 0x1d6 -+ MX8MP_IOMUXC_SD1_DATA0__USDHC1_DATA0 0x1d6 -+ MX8MP_IOMUXC_SD1_DATA1__USDHC1_DATA1 0x1d6 -+ MX8MP_IOMUXC_SD1_DATA2__USDHC1_DATA2 0x1d6 -+ MX8MP_IOMUXC_SD1_DATA3__USDHC1_DATA3 0x1d6 -+ >; -+ }; -+ -+ pinctrl_usdhc1_gpio: usdhc1grp-gpio { -+ fsl,pins = < -+#define GP_USDHC1_CD <&gpio2 11 GPIO_ACTIVE_LOW> -+ MX8MP_IOMUXC_SD1_STROBE__GPIO2_IO11 0x1c4 -+ >; -+ }; -+ -+ pinctrl_usdhc2: usdhc2grp { -+ fsl,pins = < -+ MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x190 -+ MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD 0x1d0 -+ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0 0x1d0 -+ MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d0 -+ MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d0 -+ MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d0 -+ >; -+ }; -+ -+ pinctrl_usdhc2_100mhz: usdhc2grp100mhz { -+ fsl,pins = < -+ MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x194 -+ MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD 0x1d4 -+ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0 0x1d4 -+ MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d4 -+ MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d4 -+ MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d4 -+ >; -+ }; -+ -+ pinctrl_usdhc2_200mhz: usdhc2grp200mhz { -+ fsl,pins = < -+ MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x196 -+ MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD 0x1d6 -+ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0 0x1d6 -+ MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d6 -+ MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d6 -+ MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d6 -+ >; -+ }; -+ -+ pinctrl_usdhc3: usdhc3grp { -+ fsl,pins = < -+ MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x190 -+ MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD 0x1d0 -+ MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0 0x1d0 -+ MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1 0x1d0 -+ MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2 0x1d0 -+ MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3 0x1d0 -+ MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4 0x1d0 -+ MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5 0x1d0 -+ MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6 0x1d0 -+ MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7 0x1d0 -+ MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE 0x10 -+#define GP_EMMC_RESET <&gpio3 1 IRQ_TYPE_LEVEL_LOW> -+ MX8MP_IOMUXC_NAND_CE0_B__GPIO3_IO01 0x140 -+ >; -+ }; -+ -+ pinctrl_usdhc3_100mhz: usdhc3grp-100mhz { -+ fsl,pins = < -+ MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x194 -+ MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD 0x1d4 -+ MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0 0x1d4 -+ MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1 0x1d4 -+ MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2 0x1d4 -+ MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3 0x1d4 -+ MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4 0x1d4 -+ MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5 0x1d4 -+ MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6 0x1d4 -+ MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7 0x1d4 -+ MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE 0x14 -+ >; -+ }; -+ -+ pinctrl_usdhc3_200mhz: usdhc3grp-200mhz { -+ fsl,pins = < -+ MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x196 -+ MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD 0x1d6 -+ MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0 0x1d6 -+ MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1 0x1d6 -+ MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2 0x1d6 -+ MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3 0x1d6 -+ MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4 0x1d6 -+ MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5 0x1d6 -+ MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6 0x1d6 -+ MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7 0x1d6 -+ MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE 0x12 -+ >; -+ }; -+ -+ pinctrl_wdog: wdoggrp { -+ fsl,pins = < -+ MX8MP_IOMUXC_GPIO1_IO02__WDOG1_WDOG_B 0xc6 -+ >; -+ }; -+}; -+ -+/ { -+ model = "MNT Pocket Reform with i.MX8MP Module"; -+ compatible = "mntre,pocket-reform", "boundary,imx8mp-nitrogen8mp-som", "fsl,imx8mp"; -+ chassis-type = "laptop"; -+ -+ chosen { -+ stdout-path = &uart2; -+ }; -+ -+ memory@40000000 { -+ device_type = "memory"; -+ reg = <0x0 0x40000000 0 0x80000000>; -+ }; -+ -+ bt-rfkill { -+ compatible = "net,rfkill-gpio"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_bt_rfkill>; -+ name = "bt-rfkill"; -+ type = <2>; /* Bluetooth */ -+ reset-gpios = GP_BT_RFKILL_RESET; -+ status = "okay"; -+ }; -+ -+ pcie0_refclk: pcie0-refclk { -+ compatible = "fixed-clock"; -+ #clock-cells = <0>; -+ clock-frequency = <100000000>; -+ }; -+ -+ reg_main_5v: regulator-main-5v { -+ compatible = "regulator-fixed"; -+ regulator-name = "5V"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ }; -+ -+ reg_main_3v3: regulator-main-3v3 { -+ compatible = "regulator-fixed"; -+ regulator-name = "3V3"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ }; -+ -+ reg_main_usb: regulator-main-usb { -+ compatible = "regulator-fixed"; -+ regulator-name = "USB_PWR"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ vin-supply = <®_main_5v>; -+ }; -+ -+ reg_main_1v8: regulator-main-1v8 { -+ compatible = "regulator-fixed"; -+ regulator-name = "1V8"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ vin-supply = <®_main_3v3>; -+ }; -+ -+ reg_main_1v2: regulator-main-1v2 { -+ compatible = "regulator-fixed"; -+ regulator-name = "1V2"; -+ regulator-min-microvolt = <1200000>; -+ regulator-max-microvolt = <1200000>; -+ vin-supply = <®_main_5v>; -+ }; -+ -+ reg_wlan_vmmc: regulator-wlan-vmmc { -+ compatible = "regulator-fixed"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_reg_wlan_vmmc>; -+ regulator-name = "reg_wlan_vmmc"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ gpio = GP_REG_WLAN_VMMC; -+ startup-delay-us = <70000>; -+ enable-active-high; -+ }; -+ -+ reg_pcie0: regulator-pcie { -+ compatible = "regulator-fixed"; -+ regulator-name = "MPCIE_3V3"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ vin-supply = <®_main_5v>; -+ }; -+ -+ sound { -+ compatible = "simple-audio-card"; -+ status = "okay"; -+ simple-audio-card,name = "tlv320aic3100"; -+ simple-audio-card,format = "i2s"; -+ simple-audio-card,frame-master = <&codec_dai>; -+ simple-audio-card,bitclock-master = <&codec_dai>; -+ -+ simple-audio-card,widgets = -+ "Microphone", "Microphone Jack", -+ "Headphone", "Headphone Jack", -+ "Speaker", "Speaker"; -+ -+ simple-audio-card,routing = -+ "MIC1RP", "MICBIAS", -+ "MIC1RP", "Microphone Jack", -+ "Headphone Jack", "HPR", -+ "Speaker", "SPK"; -+ -+ cpu_dai: simple-audio-card,cpu { -+ sound-dai = <&sai2>; -+ }; -+ -+ codec_dai: simple-audio-card,codec { -+ sound-dai = <&tlv320aic3100>; -+ clocks = <&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_SAI2_MCLK1>; -+ }; -+ }; -+ -+ sound-wwan { -+ compatible = "simple-audio-card"; -+ simple-audio-card,name = "Modem"; -+ simple-audio-card,format = "dsp_a"; -+ simple-audio-card,frame-master = <&wwan_dai>; -+ simple-audio-card,bitclock-master = <&wwan_dai>; -+ simple-audio-card,bitclock-inversion = <&wwan_dai>; -+ -+ wwan_cpu_dai: simple-audio-card,cpu { -+ sound-dai = <&sai3>; -+ }; -+ -+ wwan_dai: simple-audio-card,codec { -+ sound-dai = <&wwan_codec>; -+ }; -+ }; -+ -+ wwan_codec: sound-wwan-codec { -+ compatible = "option,gtm601"; -+ #sound-dai-cells = <0>; -+ }; -+}; -+ -+&snvs_rtc { -+ status = "disabled"; -+}; -+ -+&uart1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_uart1>; -+ assigned-clocks = <&clk IMX8MP_CLK_UART1>; -+ assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_80M>; -+ uart-has-rtscts; -+ status = "okay"; -+ -+ bluetooth { -+ compatible = "qcom,qca9377-bt"; -+ enable-gpios = GP_BT_ENABLE; -+ max-speed = <3000000>; -+ }; -+}; -+ -+&uart2 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_uart2>; -+ status = "okay"; -+}; -+ -+&uart3 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_uart3>; -+ assigned-clocks = <&clk IMX8MP_CLK_UART3>; -+ assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_80M>; -+ status = "okay"; -+}; -+ -+&uart4 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_uart4>; -+ assigned-clocks = <&clk IMX8MP_CLK_UART4>; -+ assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_80M>; -+ status = "okay"; -+}; -+ -+&usb3_0 { -+ fsl,disable-port-power-control; -+ status = "okay"; -+}; -+ -+&usb3_1 { -+ fsl,disable-port-power-control; -+ status = "okay"; -+}; -+ -+&usb3_phy0 { -+ status = "okay"; -+}; -+ -+&usb3_phy1 { -+ status = "okay"; -+}; -+ -+&usb_dwc3_0 { -+ dr_mode = "host"; -+ status = "okay"; -+}; -+ -+&usb_dwc3_1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_usb1_vbus>; -+ dr_mode = "host"; -+ status = "okay"; -+}; -+ -+&sai2 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_sai2>; -+ assigned-clocks = <&clk IMX8MP_CLK_AUDIOMIX_SAI2_MCLK1>; -+ assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL2_OUT>; -+ assigned-clock-rates = <24576000>; -+ fsl,sai-mclk-direction-output; -+ #sound-dai-cells = <0>; -+ status = "okay"; -+}; -+ -+&sai3 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_sai3>; -+ assigned-clocks = <&clk IMX8MP_CLK_SAI3>; -+ assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL1_OUT>; -+ assigned-clock-rates = <24576000>; -+ fsl,sai-mclk-direction-output; -+ #sound-dai-cells = <0>; -+ status = "okay"; -+}; -+ -+&pwm1 { -+ //pinctrl-names = "default"; -+ //pinctrl-0 = <&pinctrl_pwm1>; -+ status = "okay"; -+}; -+ -+&pwm2 { -+ //pinctrl-names = "default"; -+ //pinctrl-0 = <&pinctrl_pwm2>; -+ status = "okay"; -+}; -+ -+&wdog1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_wdog>; -+ fsl,ext-reset-output; -+ timeout-sec = <7200>; -+ status = "okay"; -+}; -+ -+&i2c1 { -+ clock-frequency = <400000>; -+ pinctrl-names = "default", "gpio"; -+ pinctrl-0 = <&pinctrl_i2c1>; -+ pinctrl-1 = <&pinctrl_i2c1_1>; -+ scl-gpios = GP_I2C1_SCL; -+ sda-gpios = GP_I2C1_SDA; -+ status = "okay"; -+ -+ pmic: pca9450@25 { -+ reg = <0x25>; -+ compatible = "nxp,pca9450c"; -+ /* PMIC PCA9450 PMIC_nINT GPIO1_IO3 */ -+ pinctrl-0 = <&pinctrl_pmic>; -+ interrupt-parent = <&gpio1>; -+ interrupts = <3 IRQ_TYPE_LEVEL_LOW>; -+ -+ regulators { -+ buck1: BUCK1 { -+ regulator-name = "BUCK1"; -+ regulator-min-microvolt = <600000>; -+ regulator-max-microvolt = <2187500>; -+ regulator-boot-on; -+ regulator-always-on; -+ regulator-ramp-delay = <3125>; -+ }; -+ -+ buck2: BUCK2 { -+ regulator-name = "BUCK2"; -+ regulator-min-microvolt = <600000>; -+ regulator-max-microvolt = <2187500>; -+ regulator-limit-microvolt = <1025000>; -+ regulator-boot-on; -+ regulator-always-on; -+ regulator-ramp-delay = <3125>; -+ nxp,dvs-run-voltage = <950000>; -+ nxp,dvs-standby-voltage = <850000>; -+ }; -+ -+ buck4: BUCK4 { -+ regulator-name = "BUCK4"; -+ regulator-min-microvolt = <600000>; -+ regulator-max-microvolt = <3400000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ buck5: BUCK5 { -+ regulator-name = "BUCK5"; -+ regulator-min-microvolt = <600000>; -+ regulator-max-microvolt = <3400000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ buck6: BUCK6 { -+ regulator-name = "BUCK6"; -+ regulator-min-microvolt = <600000>; -+ regulator-max-microvolt = <3400000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ ldo1: LDO1 { -+ regulator-name = "LDO1"; -+ regulator-min-microvolt = <1600000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ ldo2: LDO2 { -+ regulator-name = "LDO2"; -+ regulator-min-microvolt = <800000>; -+ regulator-max-microvolt = <1150000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ ldo3: LDO3 { -+ regulator-name = "LDO3"; -+ regulator-min-microvolt = <800000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ ldo4: LDO4 { -+ regulator-name = "LDO4"; -+ regulator-min-microvolt = <800000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ ldo5: LDO5 { -+ regulator-name = "LDO5"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ }; -+ }; -+}; -+ -+&A53_0 { -+ cpu-supply = <&buck2>; -+}; -+ -+&A53_1 { -+ cpu-supply = <&buck2>; -+}; -+ -+&A53_2 { -+ cpu-supply = <&buck2>; -+}; -+ -+&A53_3 { -+ cpu-supply = <&buck2>; -+}; -+ -+&i2c2 { -+ clock-frequency = <100000>; -+ pinctrl-names = "default", "gpio"; -+ pinctrl-0 = <&pinctrl_i2c2>; -+ pinctrl-1 = <&pinctrl_i2c2_1>; -+ scl-gpios = GP_I2C2_SCL; -+ sda-gpios = GP_I2C2_SDA; -+ status = "okay"; -+}; -+ -+&i2c3 { -+ clock-frequency = <100000>; -+ pinctrl-names = "default", "gpio"; -+ pinctrl-0 = <&pinctrl_i2c3>; -+ pinctrl-1 = <&pinctrl_i2c3_1>; -+ scl-gpios = GP_I2C3_SCL; -+ sda-gpios = GP_I2C3_SDA; -+ status = "okay"; -+ -+ tlv320aic3100: codec@18 { -+ compatible = "ti,tlv320aic3100"; -+ reg = <0x18>; -+ #sound-dai-cells = <0>; -+ clocks = <&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_SAI2_MCLK1>; -+ clock-names = "mclk"; -+ ai31xx-micbias-vg = <2>; -+ -+ HPVDD-supply = <®_main_3v3>; -+ SPRVDD-supply = <®_main_5v>; -+ SPLVDD-supply = <®_main_5v>; -+ AVDD-supply = <®_main_3v3>; -+ IOVDD-supply = <®_main_3v3>; -+ DVDD-supply = <®_main_1v8>; -+ -+ status = "okay"; -+ }; -+ -+ rtc@68 { -+ compatible = "nxp,pcf8523"; -+ reg = <0x68>; -+ }; -+}; -+ -+&i2c4 { -+ clock-frequency = <100000>; -+ pinctrl-names = "default", "gpio"; -+ pinctrl-0 = <&pinctrl_i2c4>; -+ pinctrl-1 = <&pinctrl_i2c4_1>; -+ scl-gpios = GP_I2C4_SCL; -+ sda-gpios = GP_I2C4_SDA; -+ status = "disabled"; -+}; -+ -+&mipi_dsi { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ samsung,burst-clock-frequency = <972000000>; -+ samsung,esc-clock-frequency = <24000000>; -+ status = "okay"; -+ -+ panel@0 { -+ compatible = "jdi,lt070me05000"; -+ reg = <0>; -+ -+ pinctrl = <&pinctrl_panel>; -+ -+ // reset is driven by rp2040 -+ // dcdc en is also driven by rp2040 -+ // actually backlight enable -+ enable-gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>; -+ burst-mode; -+ // the dsi mode for this controller while -+ // recognizing display v1 vs v2 -+ probe-mode-lpm; -+ init-in-enable; -+ -+ port { -+ panel_in: endpoint { -+ remote-endpoint = <&mipi_dsi_out>; -+ }; -+ }; -+ }; -+ -+ ports { -+ port@1 { -+ reg = <1>; -+ mipi_dsi_out: endpoint { -+ remote-endpoint = <&panel_in>; -+ }; -+ }; -+ }; -+}; -+ -+&lcdif1 { -+ status = "okay"; -+}; -+ -+&lcdif3 { -+ status = "okay"; -+}; -+ -+&hdmi_pvi { -+ status = "okay"; -+}; -+ -+&hdmi_tx { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_hdmi>; -+ status = "okay"; -+}; -+ -+&hdmi_tx_phy { -+ status = "okay"; -+}; -+ -+&ecspi2 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_ecspi2>; -+ cs-gpios = GP_ECSPI2_CS; -+ status = "okay"; -+ -+ spidev@0 { -+ compatible = "mntre,lpc11u24"; -+ spi-max-frequency = <1000000>; -+ reg = <0>; -+ }; -+}; -+ -+&eqos { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_eqos>; -+ phy-mode = "rgmii-id"; -+ phy-handle = <ðphy0>; -+ status = "okay"; -+ -+ mdio { -+ compatible = "snps,dwmac-mdio"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ // since module 2.0, this is 0. before it was 4. -+ ethphy0: ethernet-phy { -+ //reg = <0>; -+ compatible = "ethernet-phy-ieee802.3-c22"; -+ at803x,hib-disabled; -+ eee-broken-1000t; -+ interrupts-extended = GPIRQ_EQOS_PHY; -+ //reset-gpios = GP_EQOS_RESET; -+ reg-mask = <0x90>; -+ }; -+ }; -+}; -+ -+// microsd card -+&usdhc1 { -+ assigned-clocks = <&clk IMX8MP_CLK_USDHC1_ROOT>; -+ assigned-clock-rates = <400000000>; -+ //max-frequency = <12000000>; -+ bus-width = <4>; -+ cd-gpios = GP_USDHC1_CD; -+ pinctrl-names = "default"; //, "state_100mhz", "state_200mhz"; -+ pinctrl-0 = <&pinctrl_usdhc1>, <&pinctrl_usdhc1_gpio>; -+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>, <&pinctrl_usdhc1_gpio>; -+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>, <&pinctrl_usdhc1_gpio>; -+ status = "okay"; -+ vmmc-supply = <®_main_3v3>; -+ vqmmc-supply = <®_main_3v3>; -+}; -+ -+// sdio (wifi/bt qca9733) -+&usdhc2 { -+ //assigned-clocks = <&clk IMX8MP_CLK_USDHC2_ROOT>; -+ //assigned-clock-rates = <200000000>; -+ bus-width = <4>; -+ //max-frequency = <100000000>; -+ keep-power-in-suspend; -+ no-sd-uhs-sdr104; -+ non-removable; -+ pinctrl-names = "default", "state_100mhz", "state_200mhz"; -+ pinctrl-0 = <&pinctrl_usdhc2>; -+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>; -+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>; -+ pm-ignore-notify; -+ status = "okay"; -+ vmmc-supply = <®_wlan_vmmc>; -+ vqmmc-1-8-v; -+ vqmmc-supply = <®_main_1v8>; -+}; -+ -+// emmc -+&usdhc3 { -+ bus-width = <8>; // FIXME was 4 -+ non-removable; -+ pinctrl-names = "default", "state_100mhz", "state_200mhz"; -+ pinctrl-0 = <&pinctrl_usdhc3>; -+ pinctrl-1 = <&pinctrl_usdhc3_100mhz>; -+ pinctrl-2 = <&pinctrl_usdhc3_200mhz>; -+ vmmc-supply = <®_main_3v3>; -+ vqmmc-1-8-v; -+ vqmmc-supply = <®_main_1v8>; -+ status = "okay"; -+}; -+ -+&pcie_phy { -+ fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_OUTPUT>; -+ clocks = <&hsio_blk_ctrl>; -+ phy-supply = <®_pcie0>; -+ clock-names = "ref"; -+ status = "okay"; -+ fsl,clkreq-unsupported; -+}; -+ -+&pcie { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_pcie>; -+ reset-gpio = GP_PCIE_RESET; -+ //disable-gpio = GP_PCIE_DISABLE; -+ clocks = <&clk IMX8MP_CLK_HSIO_ROOT>, -+ <&clk IMX8MP_CLK_PCIE_ROOT>, -+ <&clk IMX8MP_CLK_HSIO_AXI>; -+ clock-names = "pcie", "pcie_aux", "pcie_bus"; -+ assigned-clocks = <&clk IMX8MP_CLK_PCIE_AUX>; -+ assigned-clock-rates = <10000000>; -+ assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_50M>; -+ vpcie-supply = <®_pcie0>; -+ vph-supply = <®_pcie0>; -+ status = "okay"; -+}; -Index: linux/arch/arm64/boot/dts/freescale/imx8mp-mnt-reform2.dts -=================================================================== ---- /dev/null -+++ linux/arch/arm64/boot/dts/freescale/imx8mp-mnt-reform2.dts -@@ -0,0 +1,940 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+ -+/* -+ * Copyright 2019-2024 MNT Research GmbH -+ * Copyright 2021 Lucas Stach <dev@lynxeye.de> -+ * Copyright 2020 Boundary Devices -+*/ -+ -+/dts-v1/; -+ -+#include <dt-bindings/phy/phy-imx8-pcie.h> -+#include "imx8mp.dtsi" -+ -+&iomuxc { -+ pinctrl_eqos: eqosgrp { -+ fsl,pins = < -+ MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC 0x20 -+ MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO 0xa0 -+ MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x1f -+ MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x1f -+ MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0 0x1f -+ MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1 0x1f -+ MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2 0x1f -+ MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3 0x1f -+ -+ MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x91 -+ MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK 0x91 -+ MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0 0x91 -+ MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1 0x91 -+ MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2 0x91 -+ MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3 0x91 -+#define GP_EQOS_RESET <&gpio3 16 GPIO_ACTIVE_LOW> -+ MX8MP_IOMUXC_NAND_READY_B__GPIO3_IO16 0x100 -+#define GPIRQ_EQOS_PHY <&gpio3 14 IRQ_TYPE_LEVEL_LOW> -+ MX8MP_IOMUXC_NAND_DQS__GPIO3_IO14 0x10 -+ >; -+ }; -+ -+ pinctrl_hog: hoggrp { -+ fsl,pins = < -+ //MX8MP_IOMUXC_NAND_DATA01__GPIO3_IO07 0x119 /* J31 */ -+ MX8MP_IOMUXC_SPDIF_RX__GPIO5_IO04 0x41 /* Pin 17 */ -+ MX8MP_IOMUXC_SPDIF_EXT_CLK__GPIO5_IO05 0x41 /* Pin 19 */ -+ MX8MP_IOMUXC_SPDIF_TX__GPIO5_IO03 0x41 /* Pin 21 */ -+ MX8MP_IOMUXC_SD1_RESET_B__GPIO2_IO10 0x41 /* Pin 23 */ -+ MX8MP_IOMUXC_SD1_DATA6__GPIO2_IO08 0x41 /* Pin 25 */ -+ MX8MP_IOMUXC_SD1_DATA5__GPIO2_IO07 0x41 /* Pin 29 */ -+ //MX8MP_IOMUXC_SD1_DATA4__GPIO2_IO06 0x41 /* Pin 31 */ -+ MX8MP_IOMUXC_SAI1_MCLK__GPIO4_IO20 0x16 /* Pin 2 */ -+ MX8MP_IOMUXC_SAI1_TXD7__GPIO4_IO19 0x1c4 /* Pin 4 */ -+ >; -+ }; -+ -+ pinctrl_hdmi: hdmigrp { -+ fsl,pins = < -+ MX8MP_IOMUXC_HDMI_DDC_SCL__HDMIMIX_HDMI_SCL 0x1c3 -+ MX8MP_IOMUXC_HDMI_DDC_SDA__HDMIMIX_HDMI_SDA 0x1c3 -+ MX8MP_IOMUXC_HDMI_HPD__HDMIMIX_HDMI_HPD 0x19 -+ MX8MP_IOMUXC_HDMI_CEC__HDMIMIX_HDMI_CEC 0x19 -+ >; -+ }; -+ -+ pinctrl_bt_rfkill: bt-rfkillgrp { -+ fsl,pins = < -+#define GP_BT_RFKILL_RESET <&gpio3 9 GPIO_ACTIVE_LOW> -+ MX8MP_IOMUXC_NAND_DATA03__GPIO3_IO09 0x119 -+ >; -+ }; -+ -+ pinctrl_ecspi2: ecspi2grp { -+ fsl,pins = < -+ /* J31 */ -+ MX8MP_IOMUXC_ECSPI2_SCLK__ECSPI2_SCLK 0x82 /* Pin 20 */ -+ MX8MP_IOMUXC_ECSPI2_MOSI__ECSPI2_MOSI 0x82 /* Pin 10 */ -+ MX8MP_IOMUXC_ECSPI2_MISO__ECSPI2_MISO 0x82 /* Pin 8 */ -+#define GP_ECSPI2_CS <&gpio5 13 GPIO_ACTIVE_LOW> -+ MX8MP_IOMUXC_ECSPI2_SS0__GPIO5_IO13 0x143 /* Pin 6 */ -+ >; -+ }; -+ -+ pinctrl_i2c1: i2c1grp { -+ fsl,pins = < -+ MX8MP_IOMUXC_I2C1_SCL__I2C1_SCL 0x400001c3 -+ MX8MP_IOMUXC_I2C1_SDA__I2C1_SDA 0x400001c3 -+ >; -+ }; -+ -+ pinctrl_i2c1_1: i2c1-1grp { -+ fsl,pins = < -+#define GP_I2C1_SCL <&gpio5 14 GPIO_OPEN_DRAIN> -+ MX8MP_IOMUXC_I2C1_SCL__GPIO5_IO14 0x1c3 -+#define GP_I2C1_SDA <&gpio5 15 GPIO_OPEN_DRAIN> -+ MX8MP_IOMUXC_I2C1_SDA__GPIO5_IO15 0x1c3 -+ >; -+ }; -+ -+ pinctrl_i2c2: i2c2grp { -+ fsl,pins = < -+ MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL 0x400001c3 -+ MX8MP_IOMUXC_I2C2_SDA__I2C2_SDA 0x400001c3 -+ >; -+ }; -+ -+ pinctrl_i2c2_1: i2c2-1grp { -+ fsl,pins = < -+#define GP_I2C2_SCL <&gpio5 16 GPIO_OPEN_DRAIN> -+ MX8MP_IOMUXC_I2C2_SCL__GPIO5_IO16 0x1c3 -+#define GP_I2C2_SDA <&gpio5 17 GPIO_OPEN_DRAIN> -+ MX8MP_IOMUXC_I2C2_SDA__GPIO5_IO17 0x1c3 -+ >; -+ }; -+ -+ pinctrl_i2c3: i2c3grp { -+ fsl,pins = < -+ MX8MP_IOMUXC_I2C3_SCL__I2C3_SCL 0x400001c3 -+ MX8MP_IOMUXC_I2C3_SDA__I2C3_SDA 0x400001c3 -+ >; -+ }; -+ -+ pinctrl_i2c3_1: i2c3-1grp { -+ fsl,pins = < -+#define GP_I2C3_SCL <&gpio5 18 GPIO_OPEN_DRAIN> -+ MX8MP_IOMUXC_I2C3_SCL__GPIO5_IO18 0x1c3 -+#define GP_I2C3_SDA <&gpio5 19 GPIO_OPEN_DRAIN> -+ MX8MP_IOMUXC_I2C3_SDA__GPIO5_IO19 0x1c3 -+ >; -+ }; -+ -+ pinctrl_i2c4: i2c4grp { -+ fsl,pins = < -+ MX8MP_IOMUXC_I2C4_SCL__I2C4_SCL 0x400001c3 -+ MX8MP_IOMUXC_I2C4_SDA__I2C4_SDA 0x400001c3 -+ >; -+ }; -+ -+ pinctrl_i2c4_1: i2c4-1grp { -+ fsl,pins = < -+#define GP_I2C4_SCL <&gpio5 20 GPIO_OPEN_DRAIN> -+ MX8MP_IOMUXC_I2C4_SCL__GPIO5_IO20 0x1c3 -+#define GP_I2C4_SDA <&gpio5 21 GPIO_OPEN_DRAIN> -+ MX8MP_IOMUXC_I2C4_SDA__GPIO5_IO21 0x1c3 -+ >; -+ }; -+ -+ pinctrl_reg_wlan_vmmc: reg-wlan-vmmcgrp { -+ fsl,pins = < -+#define GP_REG_WLAN_VMMC <&gpio2 19 GPIO_ACTIVE_HIGH> -+ MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19 0x16 -+ >; -+ }; -+ -+ pinctrl_sai2: sai2grp { -+ fsl,pins = < -+ /* WM8960 */ -+ MX8MP_IOMUXC_SAI2_TXFS__AUDIOMIX_SAI2_TX_SYNC 0xd6 -+ MX8MP_IOMUXC_SAI2_RXFS__AUDIOMIX_SAI2_RX_SYNC 0xd6 -+ MX8MP_IOMUXC_SAI2_TXC__AUDIOMIX_SAI2_TX_BCLK 0xd6 -+ MX8MP_IOMUXC_SAI2_RXC__AUDIOMIX_SAI2_RX_BCLK 0xd6 -+ MX8MP_IOMUXC_SAI2_RXD0__AUDIOMIX_SAI2_RX_DATA00 0xd6 -+ MX8MP_IOMUXC_SAI2_TXD0__AUDIOMIX_SAI2_TX_DATA00 0xd6 -+ MX8MP_IOMUXC_SAI2_MCLK__AUDIOMIX_SAI2_MCLK 0xd6 -+ >; -+ }; -+ -+ pinctrl_pcie: pciegrp { -+ fsl,pins = < -+#define GP_PCIE_RESET <&gpio1 11 GPIO_ACTIVE_LOW> -+ MX8MP_IOMUXC_GPIO1_IO11__GPIO1_IO11 0x41 -+/*#define GP_PCIE_DISABLE <&gpio4 26 GPIO_ACTIVE_LOW> -+ MX8MP_IOMUXC_SAI2_TXD0__GPIO4_IO26 0x41*/ -+ >; -+ }; -+ -+ pinctrl_pmic: pmicirq { -+ fsl,pins = < -+#define GPIRQ_PMIC <&gpio3 0 IRQ_TYPE_LEVEL_LOW> -+ MX8MP_IOMUXC_NAND_ALE__GPIO3_IO00 0x41 -+ >; -+ }; -+ -+ pinctrl_pwm1: pwm1grp { -+ fsl,pins = < -+ MX8MP_IOMUXC_GPIO1_IO01__PWM1_OUT 0x100 -+ MX8MP_IOMUXC_GPIO1_IO10__GPIO1_IO10 0x149 -+ // backlight enable -+ MX8MP_IOMUXC_GPIO1_IO07__GPIO1_IO07 0x100 -+ >; -+ }; -+ -+ pinctrl_edp_bridge: edpbridgegrp { -+ fsl,pins = < -+ MX8MP_IOMUXC_GPIO1_IO04__GPIO1_IO04 0x100 -+ >; -+ }; -+ -+ pinctrl_uart1: uart1grp { -+ fsl,pins = < -+ MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX 0x140 -+ MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX 0x140 -+ MX8MP_IOMUXC_UART3_RXD__UART1_DCE_CTS 0x140 -+ MX8MP_IOMUXC_UART3_TXD__UART1_DCE_RTS 0x140 -+ >; -+ }; -+ -+ pinctrl_uart2: uart2grp { -+ fsl,pins = < -+ MX8MP_IOMUXC_UART2_RXD__UART2_DCE_RX 0x140 -+ MX8MP_IOMUXC_UART2_TXD__UART2_DCE_TX 0x140 -+ >; -+ }; -+ -+ pinctrl_uart3: uart3grp { -+ fsl,pins = < -+ MX8MP_IOMUXC_ECSPI1_SCLK__UART3_DCE_RX 0x140 -+ MX8MP_IOMUXC_ECSPI1_MOSI__UART3_DCE_TX 0x140 -+ >; -+ }; -+ -+ pinctrl_uart4: uart4grp { -+ fsl,pins = < -+ MX8MP_IOMUXC_UART4_RXD__UART4_DCE_RX 0x140 -+ MX8MP_IOMUXC_UART4_TXD__UART4_DCE_TX 0x140 -+ >; -+ }; -+ -+ pinctrl_usdhc1: usdhc1grp { -+ fsl,pins = < -+ MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK 0x190 -+ MX8MP_IOMUXC_SD1_CMD__USDHC1_CMD 0x1d0 -+ MX8MP_IOMUXC_SD1_DATA0__USDHC1_DATA0 0x1d0 -+ MX8MP_IOMUXC_SD1_DATA1__USDHC1_DATA1 0x1d0 -+ MX8MP_IOMUXC_SD1_DATA2__USDHC1_DATA2 0x1d0 -+ MX8MP_IOMUXC_SD1_DATA3__USDHC1_DATA3 0x1d0 -+ //MX8MP_IOMUXC_GPIO1_IO03__USDHC1_VSELECT 0x116 -+ >; -+ }; -+ -+ pinctrl_usdhc1_100mhz: usdhc1grp-100mhz { -+ fsl,pins = < -+ MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK 0x194 -+ MX8MP_IOMUXC_SD1_CMD__USDHC1_CMD 0x1d4 -+ MX8MP_IOMUXC_SD1_DATA0__USDHC1_DATA0 0x1d4 -+ MX8MP_IOMUXC_SD1_DATA1__USDHC1_DATA1 0x1d4 -+ MX8MP_IOMUXC_SD1_DATA2__USDHC1_DATA2 0x1d4 -+ MX8MP_IOMUXC_SD1_DATA3__USDHC1_DATA3 0x1d4 -+ >; -+ }; -+ -+ pinctrl_usdhc1_200mhz: usdhc1grp-200mhz { -+ fsl,pins = < -+ MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK 0x196 -+ MX8MP_IOMUXC_SD1_CMD__USDHC1_CMD 0x1d6 -+ MX8MP_IOMUXC_SD1_DATA0__USDHC1_DATA0 0x1d6 -+ MX8MP_IOMUXC_SD1_DATA1__USDHC1_DATA1 0x1d6 -+ MX8MP_IOMUXC_SD1_DATA2__USDHC1_DATA2 0x1d6 -+ MX8MP_IOMUXC_SD1_DATA3__USDHC1_DATA3 0x1d6 -+ >; -+ }; -+ -+ pinctrl_usdhc1_gpio: usdhc1grp-gpio { -+ fsl,pins = < -+#define GP_USDHC1_CD <&gpio2 11 GPIO_ACTIVE_LOW> -+ MX8MP_IOMUXC_SD1_STROBE__GPIO2_IO11 0x1c4 -+ >; -+ }; -+ -+ pinctrl_usdhc2: usdhc2grp { -+ fsl,pins = < -+ MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x190 -+ MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD 0x1d0 -+ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0 0x1d0 -+ MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d0 -+ MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d0 -+ MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d0 -+ >; -+ }; -+ -+ pinctrl_usdhc2_100mhz: usdhc2grp100mhz { -+ fsl,pins = < -+ MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x194 -+ MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD 0x1d4 -+ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0 0x1d4 -+ MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d4 -+ MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d4 -+ MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d4 -+ >; -+ }; -+ -+ pinctrl_usdhc2_200mhz: usdhc2grp200mhz { -+ fsl,pins = < -+ MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x196 -+ MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD 0x1d6 -+ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0 0x1d6 -+ MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d6 -+ MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d6 -+ MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d6 -+ >; -+ }; -+ -+ pinctrl_usdhc3: usdhc3grp { -+ fsl,pins = < -+ MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x190 -+ MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD 0x1d0 -+ MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0 0x1d0 -+ MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1 0x1d0 -+ MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2 0x1d0 -+ MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3 0x1d0 -+ MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4 0x1d0 -+ MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5 0x1d0 -+ MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6 0x1d0 -+ MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7 0x1d0 -+ MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE 0x10 -+#define GP_EMMC_RESET <&gpio3 1 IRQ_TYPE_LEVEL_LOW> -+ MX8MP_IOMUXC_NAND_CE0_B__GPIO3_IO01 0x140 -+ >; -+ }; -+ -+ pinctrl_usdhc3_100mhz: usdhc3grp-100mhz { -+ fsl,pins = < -+ MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x194 -+ MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD 0x1d4 -+ MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0 0x1d4 -+ MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1 0x1d4 -+ MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2 0x1d4 -+ MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3 0x1d4 -+ MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4 0x1d4 -+ MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5 0x1d4 -+ MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6 0x1d4 -+ MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7 0x1d4 -+ MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE 0x14 -+ >; -+ }; -+ -+ pinctrl_usdhc3_200mhz: usdhc3grp-200mhz { -+ fsl,pins = < -+ MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x196 -+ MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD 0x1d6 -+ MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0 0x1d6 -+ MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1 0x1d6 -+ MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2 0x1d6 -+ MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3 0x1d6 -+ MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4 0x1d6 -+ MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5 0x1d6 -+ MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6 0x1d6 -+ MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7 0x1d6 -+ MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE 0x12 -+ >; -+ }; -+ -+ pinctrl_wdog: wdoggrp { -+ fsl,pins = < -+ MX8MP_IOMUXC_GPIO1_IO02__WDOG1_WDOG_B 0xc6 -+ >; -+ }; -+}; -+ -+/ { -+ model = "MNT Reform 2 with i.MX8MP Module"; -+ compatible = "mntre,reform2", "boundary,imx8mq-nitrogen8mp-som", "fsl,imx8mp"; -+ chassis-type = "laptop"; -+ -+ chosen { -+ stdout-path = &uart2; -+ }; -+ -+ memory@40000000 { -+ device_type = "memory"; -+ reg = <0x0 0x40000000 0 0x80000000>; -+ }; -+ -+ bt-rfkill { -+ compatible = "net,rfkill-gpio"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_bt_rfkill>; -+ name = "bt-rfkill"; -+ type = <2>; /* Bluetooth */ -+ reset-gpios = GP_BT_RFKILL_RESET; -+ status = "okay"; -+ }; -+ -+ backlight: backlight { -+ compatible = "pwm-backlight"; -+ pwms = <&pwm1 0 10000 0>; -+ power-supply = <®_main_usb>; -+ enable-gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>; -+ brightness-levels = <0 8 16 32 64 128 160 200 255>; -+ default-brightness-level = <8>; -+ }; -+ -+ panel { -+ compatible = "innolux,n125hce-gn1", "simple-panel"; -+ power-supply = <®_main_3v3>; -+ backlight = <&backlight>; -+ no-hpd; -+ -+ port { -+ panel_in: endpoint { -+ remote-endpoint = <&edp_bridge_out>; -+ }; -+ }; -+ }; -+ -+ /*dp0: connector { -+ compatible = "dp-connector"; -+ label = "DP-1"; -+ type = "full-size"; -+ dp-pwr-supply = <®_main_3v3>; -+ -+ port { -+ panel_in: endpoint { -+ remote-endpoint = <&edp_bridge_out>; -+ }; -+ }; -+ };*/ -+ -+ pcie0_refclk: pcie0-refclk { -+ compatible = "fixed-clock"; -+ #clock-cells = <0>; -+ clock-frequency = <100000000>; -+ }; -+ -+ reg_main_5v: regulator-main-5v { -+ compatible = "regulator-fixed"; -+ regulator-name = "5V"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ }; -+ -+ reg_main_3v3: regulator-main-3v3 { -+ compatible = "regulator-fixed"; -+ regulator-name = "3V3"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ }; -+ -+ reg_main_usb: regulator-main-usb { -+ compatible = "regulator-fixed"; -+ regulator-name = "USB_PWR"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ vin-supply = <®_main_5v>; -+ }; -+ -+ reg_main_1v8: regulator-main-1v8 { -+ compatible = "regulator-fixed"; -+ regulator-name = "1V8"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ vin-supply = <®_main_3v3>; -+ }; -+ -+ reg_main_1v2: regulator-main-1v2 { -+ compatible = "regulator-fixed"; -+ regulator-name = "1V2"; -+ regulator-min-microvolt = <1200000>; -+ regulator-max-microvolt = <1200000>; -+ vin-supply = <®_main_5v>; -+ }; -+ -+ reg_wlan_vmmc: regulator-wlan-vmmc { -+ compatible = "regulator-fixed"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_reg_wlan_vmmc>; -+ regulator-name = "reg_wlan_vmmc"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ gpio = GP_REG_WLAN_VMMC; -+ startup-delay-us = <70000>; -+ enable-active-high; -+ }; -+ -+ reg_pcie0: regulator-pcie { -+ compatible = "regulator-fixed"; -+ regulator-name = "MPCIE_3V3"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ vin-supply = <®_main_5v>; -+ }; -+ -+ sound { -+ compatible = "fsl,imx-audio-wm8960"; -+ audio-cpu = <&sai2>; -+ audio-codec = <&wm8960>; -+ audio-routing = -+ "Headphone Jack", "HP_L", -+ "Headphone Jack", "HP_R", -+ "Ext Spk", "SPK_LP", -+ "Ext Spk", "SPK_LN", -+ "Ext Spk", "SPK_RP", -+ "Ext Spk", "SPK_RN", -+ "LINPUT1", "Mic Jack", -+ "Mic Jack", "MICB", -+ "LINPUT2", "Line In Jack", -+ "RINPUT2", "Line In Jack"; -+ model = "wm8960-audio"; -+ }; -+}; -+ -+&snvs_rtc { -+ status = "disabled"; -+}; -+ -+&uart1 { /* BT */ -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_uart1>; -+ assigned-clocks = <&clk IMX8MP_CLK_UART1>; -+ assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_80M>; -+ uart-has-rtscts; -+ status = "okay"; -+}; -+ -+&uart2 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_uart2>; -+ status = "okay"; -+}; -+ -+&usb3_phy0 { -+ status = "okay"; -+}; -+ -+&usb3_phy1 { -+ status = "okay"; -+}; -+ -+&usb_dwc3_0 { -+ dr_mode = "host"; -+ status = "okay"; -+}; -+ -+&usb_dwc3_1 { -+ dr_mode = "host"; -+ status = "okay"; -+}; -+ -+&sai2 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_sai2>; -+ assigned-clocks = <&clk IMX8MP_CLK_SAI2>; -+ assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL1_OUT>; -+ assigned-clock-rates = <12288000>; -+ fsl,sai-mclk-direction-output; -+ fsl,sai-asynchronous; -+ status = "okay"; -+}; -+ -+&pwm1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_pwm1>; -+ status = "okay"; -+}; -+ -+&usb3_0 { -+ fsl,disable-port-power-control; -+ status = "okay"; -+}; -+ -+&usb3_1 { -+ fsl,disable-port-power-control; -+ status = "okay"; -+}; -+ -+&wdog1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_wdog>; -+ fsl,ext-reset-output; -+ timeout-sec = <7200>; -+ status = "okay"; -+}; -+ -+&wdog2 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_wdog>; -+ fsl,ext-reset-output; -+ timeout-sec = <7200>; -+ status = "okay"; -+}; -+ -+&wdog3 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_wdog>; -+ fsl,ext-reset-output; -+ timeout-sec = <7200>; -+ status = "okay"; -+}; -+ -+&i2c1 { -+ clock-frequency = <400000>; -+ pinctrl-names = "default", "gpio"; -+ pinctrl-0 = <&pinctrl_i2c1>; -+ pinctrl-1 = <&pinctrl_i2c1_1>; -+ scl-gpios = GP_I2C1_SCL; -+ sda-gpios = GP_I2C1_SDA; -+ status = "okay"; -+ -+ pmic: pca9450@25 { -+ reg = <0x25>; -+ compatible = "nxp,pca9450c"; -+ /* PMIC PCA9450 PMIC_nINT GPIO1_IO3 */ -+ pinctrl-0 = <&pinctrl_pmic>; -+ interrupt-parent = <&gpio1>; -+ interrupts = <3 IRQ_TYPE_LEVEL_LOW>; -+ -+ regulators { -+ buck1: BUCK1 { -+ regulator-name = "BUCK1"; -+ regulator-min-microvolt = <600000>; -+ regulator-max-microvolt = <2187500>; -+ regulator-boot-on; -+ regulator-always-on; -+ regulator-ramp-delay = <3125>; -+ }; -+ -+ buck2: BUCK2 { -+ regulator-name = "BUCK2"; -+ regulator-min-microvolt = <600000>; -+ regulator-max-microvolt = <2187500>; -+ regulator-limit-microvolt = <1025000>; -+ regulator-boot-on; -+ regulator-always-on; -+ regulator-ramp-delay = <3125>; -+ nxp,dvs-run-voltage = <950000>; -+ nxp,dvs-standby-voltage = <850000>; -+ }; -+ -+ buck4: BUCK4 { -+ regulator-name = "BUCK4"; -+ regulator-min-microvolt = <600000>; -+ regulator-max-microvolt = <3400000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ buck5: BUCK5 { -+ regulator-name = "BUCK5"; -+ regulator-min-microvolt = <600000>; -+ regulator-max-microvolt = <3400000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ buck6: BUCK6 { -+ regulator-name = "BUCK6"; -+ regulator-min-microvolt = <600000>; -+ regulator-max-microvolt = <3400000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ ldo1: LDO1 { -+ regulator-name = "LDO1"; -+ regulator-min-microvolt = <1600000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ ldo2: LDO2 { -+ regulator-name = "LDO2"; -+ regulator-min-microvolt = <800000>; -+ regulator-max-microvolt = <1150000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ ldo3: LDO3 { -+ regulator-name = "LDO3"; -+ regulator-min-microvolt = <800000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ ldo4: LDO4 { -+ regulator-name = "LDO4"; -+ regulator-min-microvolt = <800000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ ldo5: LDO5 { -+ regulator-name = "LDO5"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ }; -+ }; -+}; -+ -+&A53_0 { -+ cpu-supply = <&buck2>; -+}; -+ -+&A53_1 { -+ cpu-supply = <&buck2>; -+}; -+ -+&A53_2 { -+ cpu-supply = <&buck2>; -+}; -+ -+&A53_3 { -+ cpu-supply = <&buck2>; -+}; -+ -+&i2c2 { -+ clock-frequency = <100000>; -+ pinctrl-names = "default", "gpio"; -+ pinctrl-0 = <&pinctrl_i2c2>; -+ pinctrl-1 = <&pinctrl_i2c2_1>; -+ scl-gpios = GP_I2C2_SCL; -+ sda-gpios = GP_I2C2_SDA; -+ status = "okay"; -+}; -+ -+&i2c3 { -+ clock-frequency = <100000>; -+ pinctrl-names = "default", "gpio"; -+ pinctrl-0 = <&pinctrl_i2c3>; -+ pinctrl-1 = <&pinctrl_i2c3_1>; -+ scl-gpios = GP_I2C3_SCL; -+ sda-gpios = GP_I2C3_SDA; -+ status = "okay"; -+ -+ wm8960: codec@1a { -+ compatible = "wlf,wm8960"; -+ reg = <0x1a>; -+ clocks = <&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_SAI2_MCLK1>; -+ clock-names = "mclk"; -+ SPKVDD1-supply = <®_main_5v>; -+ #sound-dai-cells = <0>; -+ }; -+ -+ rtc@68 { -+ compatible = "nxp,pcf8523"; -+ reg = <0x68>; -+ }; -+}; -+ -+&i2c4 { -+ clock-frequency = <100000>; -+ pinctrl-names = "default", "gpio"; -+ pinctrl-0 = <&pinctrl_i2c4>; -+ pinctrl-1 = <&pinctrl_i2c4_1>; -+ scl-gpios = GP_I2C4_SCL; -+ sda-gpios = GP_I2C4_SDA; -+ status = "okay"; -+ -+ edp_bridge: bridge@2c { -+ compatible = "ti,sn65dsi86"; -+ burst-mode; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_edp_bridge>; -+ reg = <0x2c>; -+ enable-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>; -+ vccio-supply = <®_main_1v8>; -+ vpll-supply = <®_main_1v8>; -+ vcca-supply = <®_main_1v2>; -+ vcc-supply = <®_main_1v2>; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ port@0 { -+ reg = <0>; -+ -+ edp_bridge_in: endpoint { -+ remote-endpoint = <&mipi_dsi_out>; -+ }; -+ }; -+ -+ port@1 { -+ reg = <1>; -+ -+ edp_bridge_out: endpoint { -+ data-lanes = <0 1>; -+ remote-endpoint = <&panel_in>; -+ }; -+ }; -+ }; -+ }; -+}; -+ -+&mipi_dsi { -+ status = "okay"; -+ samsung,burst-clock-frequency = <972000000>; -+ samsung,esc-clock-frequency = <24000000>; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ port@1 { -+ reg = <1>; -+ mipi_dsi_out: endpoint { -+ remote-endpoint = <&edp_bridge_in>; -+ }; -+ }; -+ }; -+}; -+ -+&lcdif1 { -+ status = "okay"; -+}; -+ -+&lcdif3 { -+ status = "okay"; -+}; -+ -+&hdmi_pvi { -+ status = "okay"; -+}; -+ -+&hdmi_tx { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_hdmi>; -+ status = "okay"; -+}; -+ -+&hdmi_tx_phy { -+ status = "okay"; -+}; -+ -+&ecspi2 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_ecspi2>; -+ cs-gpios = GP_ECSPI2_CS; -+ status = "okay"; -+ -+ spidev@0 { -+ compatible = "mntre,lpc11u24"; -+ spi-max-frequency = <1000000>; -+ reg = <0>; -+ }; -+}; -+ -+&eqos { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_eqos>; -+ phy-mode = "rgmii-id"; -+ phy-handle = <ðphy0>; -+ status = "okay"; -+ -+ mdio { -+ compatible = "snps,dwmac-mdio"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ // since module 2.0, this is 0. before it was 4. -+ ethphy0: ethernet-phy { -+ //reg = <0>; -+ compatible = "ethernet-phy-ieee802.3-c22"; -+ at803x,hib-disabled; -+ eee-broken-1000t; -+ interrupts-extended = GPIRQ_EQOS_PHY; -+ //reset-gpios = GP_EQOS_RESET; -+ reg-mask = <0x90>; -+ }; -+ }; -+}; -+ -+// microsd card -+&usdhc1 { -+ assigned-clocks = <&clk IMX8MP_CLK_USDHC1_ROOT>; -+ assigned-clock-rates = <400000000>; -+ //max-frequency = <12000000>; -+ bus-width = <4>; -+ cd-gpios = GP_USDHC1_CD; -+ pinctrl-names = "default"; //, "state_100mhz", "state_200mhz"; -+ pinctrl-0 = <&pinctrl_usdhc1>, <&pinctrl_usdhc1_gpio>; -+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>, <&pinctrl_usdhc1_gpio>; -+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>, <&pinctrl_usdhc1_gpio>; -+ status = "okay"; -+ vmmc-supply = <®_main_3v3>; -+ vqmmc-supply = <®_main_3v3>; -+}; -+ -+// sdio (wifi/bt qca9733) -+&usdhc2 { -+ //assigned-clocks = <&clk IMX8MP_CLK_USDHC2_ROOT>; -+ //assigned-clock-rates = <200000000>; -+ bus-width = <4>; -+ //max-frequency = <100000000>; -+ keep-power-in-suspend; -+ no-sd-uhs-sdr104; -+ non-removable; -+ pinctrl-names = "default", "state_100mhz", "state_200mhz"; -+ pinctrl-0 = <&pinctrl_usdhc2>; -+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>; -+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>; -+ pm-ignore-notify; -+ status = "okay"; -+ vmmc-supply = <®_wlan_vmmc>; -+ vqmmc-1-8-v; -+ vqmmc-supply = <®_main_1v8>; -+}; -+ -+// emmc -+&usdhc3 { -+ bus-width = <8>; -+ non-removable; -+ pinctrl-names = "default", "state_100mhz", "state_200mhz"; -+ pinctrl-0 = <&pinctrl_usdhc3>; -+ pinctrl-1 = <&pinctrl_usdhc3_100mhz>; -+ pinctrl-2 = <&pinctrl_usdhc3_200mhz>; -+ vmmc-supply = <®_main_3v3>; -+ vqmmc-1-8-v; -+ vqmmc-supply = <®_main_1v8>; -+ status = "okay"; -+}; -+ -+&pcie_phy { -+ fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_OUTPUT>; -+ clocks = <&hsio_blk_ctrl>; -+ phy-supply = <®_pcie0>; -+ clock-names = "ref"; -+ status = "okay"; -+ fsl,clkreq-unsupported; -+}; -+ -+&pcie { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_pcie>; -+ reset-gpio = GP_PCIE_RESET; -+ //disable-gpio = GP_PCIE_DISABLE; -+ clocks = <&clk IMX8MP_CLK_HSIO_ROOT>, -+ <&clk IMX8MP_CLK_PCIE_ROOT>, -+ <&clk IMX8MP_CLK_HSIO_AXI>; -+ clock-names = "pcie", "pcie_aux", "pcie_bus"; -+ assigned-clocks = <&clk IMX8MP_CLK_PCIE_AUX>; -+ assigned-clock-rates = <10000000>; -+ assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_50M>; -+ vpcie-supply = <®_pcie0>; -+ vph-supply = <®_pcie0>; -+ status = "okay"; -+}; -Index: linux/arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2-hdmi.dts -=================================================================== ---- /dev/null -+++ linux/arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2-hdmi.dts -@@ -0,0 +1,836 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+* Copyright 2018 Boundary Devices -+* Copyright 2019-2021 MNT Research GmbH -+*/ -+ -+/dts-v1/; -+ -+#include "dt-bindings/input/input.h" -+#include "dt-bindings/pwm/pwm.h" -+#include "dt-bindings/usb/pd.h" -+#include "dt-bindings/gpio/gpio.h" -+#include "imx8mq.dtsi" -+ -+/ { -+ model = "MNT Reform 2"; -+ compatible = "boundary,imx8mq-nitrogen8m_som", "fsl,imx8mq"; -+ chassis-type = "laptop"; -+ -+ chosen { -+ stdout-path = "serial0:115200n8"; -+ }; -+ -+ // 4GB of RAM -+ memory@40000000 { -+ device_type = "memory"; -+ reg = <0x00000000 0x40000000 0 0xc0000000>; // TODO: confirm what this means -+ }; -+ -+ reg_vref_0v9: regulator-vref-0v9 { -+ compatible = "regulator-fixed"; -+ regulator-name = "vref-0v9"; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <900000>; -+ regulator-always-on; -+ }; -+ -+ reg_vref_1v2: regulator-vref-1v2 { -+ compatible = "regulator-fixed"; -+ regulator-name = "vref-1v2"; -+ regulator-min-microvolt = <1200000>; -+ regulator-max-microvolt = <1200000>; -+ regulator-always-on; -+ }; -+ -+ reg_vref_1v8: regulator-vref-1v8 { -+ compatible = "regulator-fixed"; -+ regulator-name = "vref-1v8"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+ }; -+ -+ reg_vref_2v5: regulator-vref-2v5 { -+ compatible = "regulator-fixed"; -+ regulator-name = "vref-2v5"; -+ regulator-min-microvolt = <2500000>; -+ regulator-max-microvolt = <2500000>; -+ regulator-always-on; -+ }; -+ -+ reg_vref_3v3: regulator-vref-3v3 { -+ compatible = "regulator-fixed"; -+ regulator-name = "vref-3v3"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ }; -+ -+ reg_vref_5v: regulator-vref-5v { -+ compatible = "regulator-fixed"; -+ regulator-name = "vref-5v"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ regulator-always-on; -+ }; -+ -+ reg_main_1v8: regulator-main-1v8 { -+ compatible = "regulator-fixed"; -+ regulator-name = "1V8"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ vin-supply = <®_vref_3v3>; -+ }; -+ -+ reg_main_1v2: regulator-main-1v2 { -+ compatible = "regulator-fixed"; -+ regulator-name = "1V2"; -+ regulator-min-microvolt = <1200000>; -+ regulator-max-microvolt = <1200000>; -+ vin-supply = <®_vref_5v>; -+ }; -+ -+ backlight: backlight { -+ compatible = "pwm-backlight"; -+ pwms = <&pwm2 0 10000 0>; -+ enable-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; -+ brightness-levels = <0 8 16 32 64 128 160 200 255>; -+ default-brightness-level = <8>; -+ }; -+ -+ panel { -+ compatible = "innolux,n125hce-gn1", "simple-panel"; -+ power-supply = <®_vref_3v3>; -+ backlight = <&backlight>; -+ no-hpd; -+ -+ port { -+ panel_in: endpoint { -+ remote-endpoint = <&edp_bridge_out>; -+ }; -+ }; -+ }; -+ -+ sound { -+ compatible = "fsl,imx-audio-wm8960"; -+ audio-cpu = <&sai2>; -+ audio-codec = <&wm8960>; -+ audio-routing = -+ "Headphone Jack", "HP_L", -+ "Headphone Jack", "HP_R", -+ "Ext Spk", "SPK_LP", -+ "Ext Spk", "SPK_LN", -+ "Ext Spk", "SPK_RP", -+ "Ext Spk", "SPK_RN", -+ "LINPUT1", "Mic Jack", -+ "Mic Jack", "MICB", -+ "LINPUT2", "Line In Jack", -+ "RINPUT2", "Line In Jack"; -+ model = "wm8960-audio"; -+ }; -+ -+ pcie1_refclk: pcie1-refclk { -+ compatible = "fixed-clock"; -+ #clock-cells = <0>; -+ clock-frequency = <100000000>; -+ }; -+}; -+ -+&A53_0 { -+ cpu-supply = <®_arm_dram>; -+}; -+ -+&A53_1 { -+ cpu-supply = <®_arm_dram>; -+}; -+ -+&A53_2 { -+ cpu-supply = <®_arm_dram>; -+}; -+ -+&A53_3 { -+ cpu-supply = <®_arm_dram>; -+}; -+ -+/ { -+ soc@0 { -+ bus@32c00000 { -+ dcss: display-controller@32e00000 { -+ status = "okay"; -+ -+ compatible = "nxp,imx8mq-dcss"; -+ reg = <0x32e00000 0x2d000>, <0x32e2f000 0x1000>; -+ interrupts = <6>, <8>, <9>; -+ interrupt-names = "ctxld", "ctxld_kick", "vblank"; -+ interrupt-parent = <&irqsteer>; -+ clocks = <&clk IMX8MQ_CLK_DISP_APB_ROOT>, -+ <&clk IMX8MQ_CLK_DISP_AXI_ROOT>, -+ <&clk IMX8MQ_CLK_DISP_RTRM_ROOT>, -+ <&clk IMX8MQ_CLK_DC_PIXEL>, -+ <&clk IMX8MQ_CLK_DISP_DTRC>, -+ <&clk IMX8MQ_VIDEO2_PLL1_REF_SEL>, -+ <&hdmi_phy_27m>; -+ clock-names = "apb", "axi", "rtrm", "pix", "dtrc", "pll_src", "pll_phy_ref"; -+ assigned-clocks = <&clk IMX8MQ_CLK_DISP_AXI>, -+ <&clk IMX8MQ_CLK_DISP_RTRM>, -+ <&clk IMX8MQ_VIDEO2_PLL1_REF_SEL>, -+ <&clk IMX8MQ_VIDEO_PLL1_REF_SEL>, -+ <&clk IMX8MQ_CLK_DC_PIXEL>; -+ assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_800M>, -+ <&clk IMX8MQ_SYS1_PLL_800M>, -+ <&clk IMX8MQ_CLK_27M>, -+ <&clk IMX8MQ_CLK_25M>, -+ <&clk IMX8MQ_VIDEO_PLL1_OUT>; -+ assigned-clock-rates = <800000000>, -+ <400000000>, -+ <27000000>, -+ <25000000>, -+ <594000000>; -+ -+ // internal display (MIPI-DSI/eDP) -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ port@0 { -+ reg = <0>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ dcss_dsi_out: endpoint@0 { -+ reg = <0>; -+ remote-endpoint = <&mipi_dsi_in>; -+ }; -+ }; -+ }; -+ }; -+ }; -+ }; -+}; -+ -+// LCDIF is not used, but has to be active or DCSS won't work -+&lcdif { -+ status = "okay"; -+ /delete-node/ port; -+}; -+ -+&dphy { -+ status = "okay"; -+ assigned-clocks = <&clk IMX8MQ_CLK_DSI_PHY_REF>; -+ assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_800M>; -+ assigned-clock-rates = <25000000>; -+}; -+ -+&fec1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_fec1>; -+ phy-mode = "rgmii-id"; -+ phy-handle = <ðphy0>; -+ fsl,magic-packet; -+ status = "okay"; -+ -+ mdio { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ ethphy0: ethernet-phy@4 { -+ compatible = "ethernet-phy-ieee802.3-c22"; -+ reg = <4>; -+ interrupts = <&gpio1 11 IRQ_TYPE_LEVEL_LOW>; -+ reset-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; -+ reset-assert-us = <10000>; -+ reset-deassert-us = <300>; -+ }; -+ }; -+}; -+ -+&i2c1 { -+ clock-frequency = <400000>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_i2c1>; -+ status = "okay"; -+ -+ // I2C Mux on Nitrogen8M_SOM -+ i2cmux@70 { -+ compatible = "nxp,pca9546"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_i2c1_pca9546>; -+ reg = <0x70>; -+ reset-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ i2c1a: i2c1@0 { -+ reg = <0>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ // Regulator on Nitrogen8M_SOM -+ reg_arm_dram: fan53555@60 { -+ compatible = "fcs,fan53555"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_reg_arm_dram>; -+ reg = <0x60>; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <1000000>; -+ regulator-ramp-delay = <8000>; -+ regulator-always-on; -+ vsel-gpios = <&gpio3 24 GPIO_ACTIVE_HIGH>; -+ }; -+ }; -+ -+ i2c1b: i2c1@1 { -+ reg = <1>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ // Regulator on Nitrogen8M_SOM -+ reg_dram_1p1v: fan53555@60 { -+ compatible = "fcs,fan53555"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_reg_dram_1p1v>; -+ reg = <0x60>; -+ regulator-min-microvolt = <1100000>; -+ regulator-max-microvolt = <1100000>; -+ regulator-ramp-delay = <8000>; -+ regulator-always-on; -+ vsel-gpios = <&gpio2 11 GPIO_ACTIVE_HIGH>; -+ }; -+ }; -+ -+ i2c1c: i2c1@2 { -+ reg = <2>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ // Regulator on Nitrogen8M_SOM -+ reg_soc_gpu_vpu: fan53555@60 { -+ compatible = "fcs,fan53555"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_reg_soc_gpu_vpu>; -+ reg = <0x60>; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <1000000>; -+ regulator-ramp-delay = <8000>; -+ regulator-always-on; -+ vsel-gpios = <&gpio2 20 GPIO_ACTIVE_HIGH>; -+ }; -+ }; -+ -+ // No peripheral connected, available on DSI connector -+ i2c1d: i2c1@3 { -+ reg = <3>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ }; -+}; -+ -+// No peripheral connected, available on CSI connector -+&i2c2 { -+ status = "disabled"; -+}; -+ -+&i2c3 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_i2c3>; -+ status = "okay"; -+ -+ // Audio chip on motherboard -+ wm8960: codec@1a { -+ compatible = "wlf,wm8960"; -+ reg = <0x1a>; -+ clocks = <&clk IMX8MQ_CLK_SAI2_ROOT>; -+ clock-names = "mclk"; -+ #sound-dai-cells = <0>; -+ }; -+ -+ // Realtime clock chip on motherboard -+ pcf8523: pcf8523@68 { -+ compatible = "nxp,pcf8523"; -+ reg = <0x68>; -+ }; -+}; -+ -+&i2c4 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_i2c4>; -+ status = "okay"; -+ -+ // DSI to eDP converter on motherboard -+ edp_bridge: sn65dsi86@2c { -+ compatible = "ti,sn65dsi86"; -+ reg = <0x2c>; -+ enable-gpios = <&gpio3 20 GPIO_ACTIVE_HIGH>; -+ vccio-supply = <®_main_1v8>; -+ vpll-supply = <®_main_1v8>; -+ vcca-supply = <®_main_1v2>; -+ vcc-supply = <®_main_1v2>; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ port@0 { -+ reg = <0>; -+ -+ edp_bridge_in: endpoint { -+ remote-endpoint = <&mipi_dsi_out>; -+ }; -+ }; -+ -+ port@1 { -+ reg = <1>; -+ -+ edp_bridge_out: endpoint { -+ remote-endpoint = <&panel_in>; -+ }; -+ }; -+ }; -+ }; -+}; -+ -+// TODO: add external pin numbers -+&iomuxc { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_hog>; -+ -+ pinctrl_hog: hoggrp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_SAI5_RXC_GPIO3_IO20 0x19 // WL_EN on Nitrogen8M_SOM, pin 38, goes to /EN input of SN65DSI86 -+ MX8MQ_IOMUXC_GPIO1_IO14_GPIO1_IO14 0x56 // TODO: check pullup of usb hub reset on the board (0x40) -+ >; -+ }; -+ -+ pinctrl_fec1: fec1grp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_ENET_MDC_ENET1_MDC 0x3 -+ MX8MQ_IOMUXC_ENET_MDIO_ENET1_MDIO 0x23 -+ MX8MQ_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x1f -+ MX8MQ_IOMUXC_ENET_TXC_ENET1_RGMII_TXC 0x1f -+ MX8MQ_IOMUXC_ENET_TD0_ENET1_RGMII_TD0 0x1f -+ MX8MQ_IOMUXC_ENET_TD1_ENET1_RGMII_TD1 0x1f -+ MX8MQ_IOMUXC_ENET_TD2_ENET1_RGMII_TD2 0x1f -+ MX8MQ_IOMUXC_ENET_TD3_ENET1_RGMII_TD3 0x1f -+ MX8MQ_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91 -+ MX8MQ_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0xd1 -+ MX8MQ_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 0x91 -+ MX8MQ_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 0x91 -+ MX8MQ_IOMUXC_ENET_RD2_ENET1_RGMII_RD2 0x91 -+ MX8MQ_IOMUXC_ENET_RD3_ENET1_RGMII_RD3 0xd1 -+ MX8MQ_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x1 -+ MX8MQ_IOMUXC_GPIO1_IO11_GPIO1_IO11 0x41 -+ >; -+ }; -+ -+ pinctrl_i2c1: i2c1grp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_I2C1_SCL_I2C1_SCL 0x40000022 -+ MX8MQ_IOMUXC_I2C1_SDA_I2C1_SDA 0x40000022 -+ >; -+ }; -+ -+ pinctrl_i2c1_pca9546: i2c1-pca9546grp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_GPIO1_IO04_GPIO1_IO4 0x46 -+ >; -+ }; -+ -+ pinctrl_i2c2: i2c2grp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_I2C2_SCL_I2C2_SCL 0x40000022 -+ MX8MQ_IOMUXC_I2C2_SDA_I2C2_SDA 0x40000022 -+ >; -+ }; -+ -+ pinctrl_i2c3: i2c3grp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_I2C3_SCL_I2C3_SCL 0x40000022 -+ MX8MQ_IOMUXC_I2C3_SDA_I2C3_SDA 0x40000022 -+ >; -+ }; -+ -+ pinctrl_i2c4: i2c4grp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_I2C4_SCL_I2C4_SCL 0x40000022 -+ MX8MQ_IOMUXC_I2C4_SDA_I2C4_SDA 0x40000022 -+ >; -+ }; -+ -+ pinctrl_pcie0: pcie0grp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_ECSPI1_MOSI_GPIO5_IO7 0x16 -+ >; -+ }; -+ -+ pinctrl_pcie1: pcie1grp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_SAI5_RXD2_GPIO3_IO23 0x16 -+ >; -+ }; -+ -+ pinctrl_pwm2: pwm2grp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_SPDIF_RX_PWM2_OUT 0x16 -+ >; -+ }; -+ -+ pinctrl_pwm3: pwm3grp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_SPDIF_TX_PWM3_OUT 0x16 -+ >; -+ }; -+ -+ // Backlight -+ pinctrl_pwm4: pwm4grp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_SAI3_MCLK_PWM4_OUT 0x16 -+ >; -+ }; -+ -+ pinctrl_reg_arm_dram: reg-arm-dram { -+ fsl,pins = < -+ MX8MQ_IOMUXC_SAI5_RXD3_GPIO3_IO24 0x16 -+ >; -+ }; -+ -+ pinctrl_reg_dram_1p1v: reg-dram-1p1v { -+ fsl,pins = < -+ MX8MQ_IOMUXC_SD1_STROBE_GPIO2_IO11 0x16 -+ >; -+ }; -+ -+ pinctrl_reg_soc_gpu_vpu: reg-soc-gpu-vpu { -+ fsl,pins = < -+ MX8MQ_IOMUXC_SD2_WP_GPIO2_IO20 0x16 -+ >; -+ }; -+ -+ pinctrl_sai2: sai2grp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_SAI2_RXD0_SAI2_RX_DATA0 0xd6 /* Pin 166 */ -+ MX8MQ_IOMUXC_SAI2_RXFS_SAI2_RX_SYNC 0xd6 /* Pin 168 */ -+ MX8MQ_IOMUXC_SAI2_TXC_SAI2_TX_BCLK 0xd6 /* Pin 170 */ -+ MX8MQ_IOMUXC_SAI2_TXFS_SAI2_TX_SYNC 0xd6 /* Pin 172 */ -+ MX8MQ_IOMUXC_SAI2_RXC_SAI2_RX_BCLK 0xd6 /* Pin 174 */ -+ MX8MQ_IOMUXC_SAI2_MCLK_SAI2_MCLK 0xd6 /* Pin 176 */ -+ MX8MQ_IOMUXC_SAI2_TXD0_SAI2_TX_DATA0 0xd6 /* Pin 168 */ -+ >; -+ }; -+ -+ pinctrl_uart1: uart1grp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_UART1_RXD_UART1_DCE_RX 0x45 -+ MX8MQ_IOMUXC_UART1_TXD_UART1_DCE_TX 0x45 -+ >; -+ }; -+ -+ pinctrl_uart2: uart2grp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_UART2_RXD_UART2_DCE_RX 0x45 -+ MX8MQ_IOMUXC_UART2_TXD_UART2_DCE_TX 0x45 -+ >; -+ }; -+ -+ pinctrl_uart3: uart3grp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_UART3_RXD_UART3_DCE_RX 0x45 -+ MX8MQ_IOMUXC_UART3_TXD_UART3_DCE_TX 0x45 -+ >; -+ }; -+ -+ pinctrl_usdhc1: usdhc1grp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x83 -+ MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xc3 -+ MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xc3 -+ MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xc3 -+ MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xc3 -+ MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xc3 -+ MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xc3 -+ MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xc3 -+ MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xc3 -+ MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xc3 -+ MX8MQ_IOMUXC_SD1_RESET_B_GPIO2_IO10 0x41 -+ >; -+ }; -+ -+ pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x8d -+ MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xcd -+ MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xcd -+ MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xcd -+ MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xcd -+ MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xcd -+ MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xcd -+ MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xcd -+ MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xcd -+ MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xcd -+ >; -+ }; -+ -+ pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x9f -+ MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xdf -+ MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xdf -+ MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xdf -+ MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xdf -+ MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xdf -+ MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xdf -+ MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xdf -+ MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xdf -+ MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xdf -+ >; -+ }; -+ -+ pinctrl_usdhc2: usdhc2grp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x03 -+ MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xc3 -+ MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xc3 -+ MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xc3 -+ MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xc3 -+ MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xc -+ >; -+ }; -+ -+ pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x0d -+ MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xcd -+ MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xcd -+ MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xcd -+ MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xcd -+ MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xcd -+ >; -+ }; -+ -+ pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x1e -+ MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xce -+ MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xce -+ MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xce -+ MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xce -+ MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xce -+ >; -+ }; -+ -+ pinctrl_wdog: wdoggrp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0xc6 -+ >; -+ }; -+ -+ pinctrl_ecspi2: ecspi2grp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI 0x19 -+ MX8MQ_IOMUXC_ECSPI2_MISO_ECSPI2_MISO 0x19 -+ MX8MQ_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK 0x19 -+ >; -+ }; -+ -+ pinctrl_ecspi2_cs: ecspi2csgrp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_ECSPI2_SS0_GPIO5_IO13 0x19 -+ >; -+ }; -+}; -+ -+&mipi_dsi { -+ status = "okay"; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ port@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ -+ // We don't want input from LCDIF -+ /delete-node/ endpoint@0; -+ -+ mipi_dsi_in: endpoint@1 { -+ reg = <1>; -+ remote-endpoint = <&dcss_dsi_out>; -+ }; -+ }; -+ port@1 { -+ reg = <1>; -+ mipi_dsi_out: endpoint { -+ remote-endpoint = <&edp_bridge_in>; -+ }; -+ }; -+ }; -+}; -+ -+&pcie0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_pcie0>; -+ reset-gpio = <&gpio5 7 GPIO_ACTIVE_LOW>; -+ internal-refclk; -+ -+ clocks = <&clk IMX8MQ_CLK_PCIE1_ROOT>, -+ <&clk IMX8MQ_CLK_PCIE1_AUX>, -+ <&clk IMX8MQ_CLK_PCIE1_PHY>, -+ <&clk IMX8MQ_CLK_MON_CLK2_OUT>; -+ -+ clock-names = "pcie", "pcie_aux", "pcie_phy", "pcie_bus"; -+ -+ assigned-clocks = <&clk IMX8MQ_CLK_PCIE1_CTRL>, -+ <&clk IMX8MQ_CLK_PCIE1_PHY>, -+ <&clk IMX8MQ_CLK_MON_CLK2_OUT>; -+ assigned-clock-rates = <250000000>, -+ <100000000>, -+ <100000000>; -+ assigned-clock-parents = <&clk IMX8MQ_SYS2_PLL_250M>, -+ <&clk IMX8MQ_SYS2_PLL_100M>; -+ -+ status = "okay"; -+}; -+ -+&pcie1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_pcie1>; -+ reset-gpio = <&gpio3 23 GPIO_ACTIVE_LOW>; -+ -+ clocks = <&clk IMX8MQ_CLK_PCIE2_ROOT>, -+ <&clk IMX8MQ_CLK_PCIE2_AUX>, -+ <&clk IMX8MQ_CLK_PCIE2_PHY>, -+ <&pcie1_refclk>; -+ clock-names = "pcie", "pcie_aux", "pcie_phy", "pcie_bus"; -+ status = "okay"; -+}; -+ -+&pwm2 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_pwm2>; -+ status = "okay"; -+}; -+ -+&pwm3 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_pwm3>; -+ status = "okay"; -+}; -+ -+// Backlight control -+&pwm4 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_pwm4>; -+ status = "okay"; -+}; -+ -+&sai2 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_sai2>; -+ assigned-clocks = <&clk IMX8MQ_CLK_SAI2>; -+ assigned-clock-parents = <&clk IMX8MQ_CLK_25M>; -+ assigned-clock-rates = <25000000>; -+ status = "okay"; -+}; -+ -+// Don't use i.MX8M internal RTC because we have a dedicated one -+&snvs_rtc { -+ status = "disabled"; -+}; -+ -+// Console -+&uart1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_uart1>; -+ status = "okay"; -+}; -+ -+// Auxiliary serial port on motherboard -+&uart2 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_uart2>; -+ status = "okay"; -+}; -+ -+// connected to LPC11U24 chip on the motherboard -+&uart3 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_uart3>; -+ status = "okay"; -+}; -+ -+&usb_dwc3_0 { -+ status = "okay"; -+ dr_mode = "host"; -+}; -+ -+&usb_dwc3_1 { -+ status = "okay"; -+ dr_mode = "host"; -+}; -+ -+&usb3_phy0 { -+ vbus-supply = <®_vref_5v>; -+ status = "okay"; -+}; -+ -+&usb3_phy1 { -+ vbus-supply = <®_vref_5v>; -+ status = "okay"; -+}; -+ -+// eMMC on Nitrogen8M_SOM -+// TODO: HS currently doesn't work -+&usdhc1 { -+ bus-width = <8>; -+ fsl,strobe-dll-delay-target = <5>; -+ fsl,tuning-start-tap = <63>; -+ fsl,tuning-step = <2>; -+ non-removable; -+ no-sd; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_usdhc1>; -+ vmmc-supply = <®_vref_1v8>; -+ vqmmc-1-8-v; -+ status = "okay"; -+}; -+ -+// SD Card on motherboard -+// TODO: check keep-power-in-suspend, cap-sdio-irq -+&usdhc2 { -+ assigned-clocks = <&clk IMX8MQ_CLK_USDHC2>; -+ assigned-clock-rates = <200000000>; -+ bus-width = <4>; -+ pinctrl-names = "default", "state_100mhz", "state_200mhz"; -+ pinctrl-0 = <&pinctrl_usdhc2>; -+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>; -+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>; -+ vmmc-supply = <®_vref_3v3>; -+ vqmmc-supply = <®_vref_3v3>; -+ cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>; -+ status = "okay"; -+}; -+ -+&wdog1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_wdog>; -+ fsl,ext-reset-output; // TODO check source for what this means -+ status = "okay"; -+}; -+ -+&ecspi2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_ecspi2 &pinctrl_ecspi2_cs>; -+ cs-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>; -+ status = "okay"; -+ fsl,spi-num-chipselects = <1>; -+ -+ spidev@0 { -+ compatible = "mntre,lpc11u24"; -+ spi-max-frequency = <1000000>; -+ reg = <0>; -+ }; -+}; -Index: linux/arch/arm64/boot/dts/rockchip/Makefile -=================================================================== ---- linux.orig/arch/arm64/boot/dts/rockchip/Makefile -+++ linux/arch/arm64/boot/dts/rockchip/Makefile -@@ -140,6 +140,9 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-or - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-quartzpro64.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-rock-5-itx.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-rock-5b.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-mnt-reform2.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-mnt-reform-next.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-mnt-pocket-reform.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-rock-5b-pcie-ep.dtbo - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-rock-5b-pcie-srns.dtbo - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-tiger-haikou.dtb -Index: linux/arch/arm64/boot/dts/rockchip/rk3588-mnt-pocket-reform.dts -=================================================================== ---- /dev/null -+++ linux/arch/arm64/boot/dts/rockchip/rk3588-mnt-pocket-reform.dts -@@ -0,0 +1,1034 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Copyright (c) 2021 Rockchip Electronics Co., Ltd. -+ * Copyright (c) 2024 MNT Research GmbH -+ * -+ */ -+ -+/dts-v1/; -+ -+#include <dt-bindings/gpio/gpio.h> -+#include <dt-bindings/input/input.h> -+#include <dt-bindings/pinctrl/rockchip.h> -+#include <dt-bindings/usb/pd.h> -+#include <dt-bindings/soc/rockchip,vop2.h> -+#include "rk3588.dtsi" -+ -+/ { -+ model = "MNT Pocket Reform with RCORE RK3588 Module"; -+ compatible = "mntre,pocket-reform-rcore", "firefly,icore3588q", "rockchip,rk3588"; -+ -+ aliases { -+ ethernet0 = &gmac0; -+ serial2 = &uart2; -+ mmc0 = &sdhci; -+ mmc1 = &sdmmc; -+ }; -+ -+ chosen { -+ stdout-path = "serial2:1500000n8"; -+ }; -+ -+ analog-sound { -+ compatible = "audio-graph-card"; -+ label = "rk3588-tlv320aic3100"; -+ -+ widgets = -+ "Headphone", "Headphone Jack", -+ "Microphone", "Microphone Jack", -+ "Speaker", "Speaker"; -+ -+ routing = -+ "MIC1RP", "MICBIAS", -+ "MIC1RP", "Microphone Jack", -+ "Headphone Jack", "HPR", -+ "Speaker", "SPK"; -+ -+ dais = <&i2s0_8ch_p0>; -+ }; -+ -+ gmac0_clkin: external-gmac0-clock { -+ compatible = "fixed-clock"; -+ clock-frequency = <125000000>; -+ clock-output-names = "gmac0_clkin"; -+ #clock-cells = <0>; -+ }; -+ -+ pcie30_avdd1v8: pcie30-avdd1v8 { -+ compatible = "regulator-fixed"; -+ regulator-name = "pcie30_avdd1v8"; -+ regulator-boot-on; -+ regulator-always-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ vin-supply = <&avcc_1v8_s0>; -+ }; -+ -+ pcie30_avdd0v75: pcie30-avdd0v75 { -+ compatible = "regulator-fixed"; -+ regulator-name = "pcie30_avdd0v75"; -+ regulator-boot-on; -+ regulator-always-on; -+ regulator-min-microvolt = <750000>; -+ regulator-max-microvolt = <750000>; -+ vin-supply = <&avdd_0v75_s0>; -+ }; -+ -+ vcc12v_dcin: vcc12v-dcin-regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc12v_dcin"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <12000000>; -+ regulator-max-microvolt = <12000000>; -+ }; -+ -+ vcc_1v1_nldo_s3: vcc-1v1-nldo-s3 { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc_1v1_nldo_s3"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1100000>; -+ regulator-max-microvolt = <1100000>; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+ -+ vcc3v3_pcie30: vcc3v3-pcie30 { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc3v3_pcie30"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-boot-on; -+ regulator-always-on; -+ vin-supply = <&vcc12v_dcin>; -+ }; -+ -+ vcc5v0_host: vcc5v0-host { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc5v0_host"; -+ regulator-boot-on; -+ regulator-always-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ }; -+ -+ 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>; -+ }; -+}; -+ -+&combphy0_ps { -+ status = "okay"; -+}; -+ -+&combphy1_ps { -+ status = "okay"; -+}; -+ -+&combphy2_psu { -+ status = "okay"; -+}; -+ -+&cpu_b0 { -+ cpu-supply = <&vdd_cpu_big0_s0>; -+ mem-supply = <&vdd_cpu_big0_s0>; -+}; -+ -+&cpu_b1 { -+ cpu-supply = <&vdd_cpu_big0_s0>; -+ mem-supply = <&vdd_cpu_big0_s0>; -+}; -+ -+&cpu_b2 { -+ cpu-supply = <&vdd_cpu_big1_s0>; -+ mem-supply = <&vdd_cpu_big1_s0>; -+}; -+ -+&cpu_b3 { -+ cpu-supply = <&vdd_cpu_big1_s0>; -+ mem-supply = <&vdd_cpu_big1_s0>; -+}; -+ -+&cpu_l0 { -+ cpu-supply = <&vdd_cpu_lit_s0>; -+ mem-supply = <&vdd_cpu_lit_mem_s0>; -+}; -+ -+&cpu_l1 { -+ cpu-supply = <&vdd_cpu_lit_s0>; -+ mem-supply = <&vdd_cpu_lit_mem_s0>; -+}; -+ -+&cpu_l2 { -+ cpu-supply = <&vdd_cpu_lit_s0>; -+ mem-supply = <&vdd_cpu_lit_mem_s0>; -+}; -+ -+&cpu_l3 { -+ cpu-supply = <&vdd_cpu_lit_s0>; -+ mem-supply = <&vdd_cpu_lit_mem_s0>; -+}; -+ -+&display_subsystem { -+ clocks = <&hdptxphy_hdmi0>, <&hdptxphy_hdmi1>; -+ clock-names = "hdmi0_phy_pll", "hdmi1_phy_pll"; -+}; -+ -+&gmac0 { -+ clock_in_out = "output"; -+ phy-handle = <&rgmii_phy>; -+ phy-mode = "rgmii-id"; -+ pinctrl-0 = <&gmac0_miim -+ &gmac0_tx_bus2 -+ &gmac0_rx_bus2 -+ &gmac0_rgmii_clk -+ &gmac0_rgmii_bus -+ &gmac0_clkinout -+ ð_phy_reset>; -+ pinctrl-names = "default"; -+ -+ /* resetting in the driver is not reliable, -+ so we do it in reform-hw-setup -+ until we have enough test data to move -+ it to u-boot */ -+ -+ /*snps,reset-gpio = <&gpio3 RK_PC7 GPIO_ACTIVE_LOW>; -+ snps,reset-active-low; -+ snps,reset-delays-us = <0 20000 100000>;*/ -+ -+ status = "okay"; -+}; -+ -+&gpu { -+ mali-supply = <&vdd_gpu_s0>; -+ sram-supply = <&vdd_gpu_mem_s0>; -+ status = "okay"; -+}; -+ -+// internal HDMI, currently unused on pocket, -+// but could be used for 3rd display -+/*&hdmi0 { -+ enable-gpios = <&gpio4 RK_PA0 GPIO_ACTIVE_HIGH>; -+ status = "okay"; -+}; -+ -+&hdmi0_in { -+ hdmi0_in_vp1: endpoint { -+ remote-endpoint = <&vp1_out_hdmi0>; -+ }; -+};*/ -+ -+&hdptxphy_hdmi0 { -+ status = "okay"; -+}; -+ -+&hdmi1 { -+ // external HDMI -+ enable-gpios = <&gpio4 RK_PB4 GPIO_ACTIVE_HIGH>; -+ status = "okay"; -+}; -+ -+&hdmi1_in { -+ hdmi1_in_vp0: endpoint { -+ remote-endpoint = <&vp0_out_hdmi1>; -+ }; -+}; -+ -+&hdptxphy_hdmi1 { -+ status = "okay"; -+}; -+ -+&i2c0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c0m2_xfer>; -+ status = "okay"; -+ -+ vdd_cpu_big0_s0: vdd_cpu_big0_mem_s0: rk8602@42 { -+ compatible = "rockchip,rk8602"; -+ reg = <0x42>; -+ -+ vin-supply = <&vcc5v0_sys>; -+ fcs,suspend-voltage-selector = <1>; -+ rockchip,suspend-voltage-selector = <1>; -+ -+ regulator-compatible = "rk860x-reg"; -+ regulator-name = "vdd_cpu_big0_s0"; -+ regulator-min-microvolt = <0x86470>; -+ regulator-max-microvolt = <0x100590>; -+ regulator-ramp-delay = <0x8fc>; -+ regulator-boot-on; -+ regulator-always-on; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdd_cpu_big1_s0: vdd_cpu_big1_mem_s0: rk8603@43 { -+ compatible = "rockchip,rk8602", "rockchip,rk8603"; -+ reg = <0x43>; -+ -+ vin-supply = <&vcc5v0_sys>; -+ fcs,suspend-voltage-selector = <1>; -+ rockchip,suspend-voltage-selector = <1>; -+ -+ regulator-compatible = "rk860x-reg"; -+ regulator-name = "vdd_cpu_big1_s0"; -+ regulator-min-microvolt = <550000>; -+ regulator-max-microvolt = <1050000>; -+ regulator-ramp-delay = <2300>; -+ regulator-boot-on; -+ regulator-always-on; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+}; -+ -+&i2c1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c1m2_xfer>; -+ status = "okay"; -+ -+ vdd_npu_s0: vdd_npu_mem_s0: regulator@42 { -+ compatible = "rockchip,rk8602"; -+ reg = <0x42>; -+ fcs,suspend-voltage-selector = <1>; -+ regulator-name = "vdd_npu_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <550000>; -+ regulator-max-microvolt = <950000>; -+ regulator-ramp-delay = <2300>; -+ vin-supply = <&vcc5v0_sys>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+}; -+ -+&i2c6 { -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c6m0_xfer>; -+ -+ tlv320aic3100: codec@18 { -+ compatible = "ti,tlv320aic3100"; -+ reg = <0x18>; -+ clocks = <&cru I2S0_8CH_MCLKOUT>; -+ clock-names = "mclk"; -+ ai31xx-micbias-vg = <2>; -+ #sound-dai-cells = <0>; -+ -+ HPVDD-supply = <&vcc_3v3_s3>; -+ SPRVDD-supply = <&vcc5v0_host>; -+ SPLVDD-supply = <&vcc5v0_host>; -+ AVDD-supply = <&vcc_3v3_s3>; -+ IOVDD-supply = <&vcc_3v3_s3>; -+ DVDD-supply = <&vcc_1v8_s3>; -+ -+ status = "okay"; -+ -+ port { -+ tlv320aic3100_p0: endpoint { -+ remote-endpoint = <&i2s0_8ch_p0_0>; -+ }; -+ }; -+ }; -+ -+ rtc@68 { -+ compatible = "nxp,pcf8523"; -+ reg = <0x68>; -+ }; -+}; -+ -+&i2s0_8ch { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2s0_lrck -+ &i2s0_mclk -+ &i2s0_sclk -+ &i2s0_sdi0 -+ &i2s0_sdo0>; -+ status = "okay"; -+ -+ i2s0_8ch_p0: port { -+ i2s0_8ch_p0_0: endpoint { -+ dai-format = "i2s"; -+ remote-endpoint = <&tlv320aic3100_p0>; -+ }; -+ }; -+}; -+ -+&pcie2x1l2 { -+ reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>; -+ pinctrl-0 = <&pcie2_0_rst>; -+ status = "okay"; -+}; -+ -+/*&pcie2x1l1 { -+ reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_LOW>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie2_1_rst>; -+ status = "okay"; -+};*/ -+ -+/*&pcie30phy { -+ status = "okay"; -+};*/ -+ -+/*&pcie3x4 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie3_reset>; -+ reset-gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_HIGH>; -+ num-lanes = <4>; -+ vpcie3v3-supply = <&vcc3v3_pcie30>; -+ status = "okay"; -+};*/ -+ -+&i2c3 { -+ status = "okay"; -+}; -+ -+&pwm8 { -+ pinctrl-0 = <&pwm8m2_pins>; -+ status = "okay"; -+}; -+ -+&saradc { -+ vref-supply = <&avcc_1v8_s0>; -+ status = "okay"; -+}; -+ -+&tsadc { -+ status = "okay"; -+}; -+ -+&sdhci { -+ bus-width = <8>; -+ no-sdio; -+ no-sd; -+ non-removable; -+ max-frequency = <150000000>; -+ mmc-hs400-1_8v; -+ mmc-hs400-enhanced-strobe; -+ status = "okay"; -+}; -+ -+&sdmmc { -+ bus-width = <4>; -+ max-frequency = <20000000>; -+ no-sdio; -+ no-mmc; -+ no-1-8-v; -+ cap-sd-highspeed; -+ vqmmc-supply = <&vcc3v3_pcie30>; -+ vmmc-supply = <&vcc3v3_pcie30>; -+ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; -+ disable-wp; -+ status = "okay"; -+}; -+ -+&spi1 { -+ status = "okay"; -+ assigned-clocks = <&cru CLK_SPI1>; -+ assigned-clock-rates = <200000000>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi1m2_cs0 &spi1m2_pins>; -+ num-cs = <1>; -+ -+ spidev@0 { -+ compatible = "mntre,lpc11u24"; -+ spi-max-frequency = <1000000>; -+ reg = <0>; -+ }; -+}; -+ -+&spi2 { -+ status = "okay"; -+ assigned-clocks = <&cru CLK_SPI2>; -+ assigned-clock-rates = <200000000>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>; -+ num-cs = <1>; -+ -+ rk806single: pmic@0 { -+ compatible = "rockchip,rk806"; -+ spi-max-frequency = <1000000>; -+ reg = <0x0>; -+ -+ interrupt-parent = <&gpio0>; -+ interrupts = <7 IRQ_TYPE_LEVEL_LOW>; -+ -+ pinctrl-names = "default", "pmic-power-off"; -+ pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>, -+ <&rk806_dvs2_null>, <&rk806_dvs3_null>; -+ pinctrl-1 = <&rk806_dvs1_pwrdn>; -+ -+ /* TODO: missing some thresholds */ -+ -+ pmic-reset-func = <1>; -+ -+ vcc1-supply = <&vcc5v0_sys>; -+ vcc2-supply = <&vcc5v0_sys>; -+ vcc3-supply = <&vcc5v0_sys>; -+ vcc4-supply = <&vcc5v0_sys>; -+ vcc5-supply = <&vcc5v0_sys>; -+ vcc6-supply = <&vcc5v0_sys>; -+ vcc7-supply = <&vcc5v0_sys>; -+ vcc8-supply = <&vcc5v0_sys>; -+ vcc9-supply = <&vcc5v0_sys>; -+ vcc10-supply = <&vcc5v0_sys>; -+ vcc11-supply = <&vcc_2v0_pldo_s3>; -+ vcc12-supply = <&vcc5v0_sys>; -+ vcc13-supply = <&vcc_1v1_nldo_s3>; -+ vcc14-supply = <&vcc_1v1_nldo_s3>; -+ vcca-supply = <&vcc5v0_sys>; -+ -+ #gpio-cells = <2>; -+ gpio-controller; -+ -+ rk806_dvs1_null: dvs1-null-pins { -+ pins = "gpio_pwrctrl2"; -+ function = "pin_fun0"; -+ }; -+ -+ rk806_dvs1_slp: rk806_dvs1_slp { -+ pins = "gpio_pwrctrl1"; -+ function = "pin_fun1"; -+ }; -+ -+ rk806_dvs1_pwrdn: rk806_dvs1_pwrdn { -+ pins = "gpio_pwrctrl1"; -+ function = "pin_fun2"; -+ }; -+ -+ rk806_dvs1_rst: rk806_dvs1_rst { -+ pins = "gpio_pwrctrl1"; -+ function = "pin_fun3"; -+ }; -+ -+ rk806_dvs2_null: rk806_dvs2_null { -+ pins = "gpio_pwrctrl2"; -+ function = "pin_fun0"; -+ }; -+ -+ rk806_dvs2_slp: rk806_dvs2_slp { -+ pins = "gpio_pwrctrl2"; -+ function = "pin_fun1"; -+ }; -+ -+ rk806_dvs2_pwrdn: rk806_dvs2_pwrdn { -+ pins = "gpio_pwrctrl2"; -+ function = "pin_fun2"; -+ }; -+ -+ rk806_dvs2_rst: rk806_dvs2_rst { -+ pins = "gpio_pwrctrl2"; -+ function = "pin_fun3"; -+ }; -+ -+ rk806_dvs2_dvs: rk806_dvs2_dvs { -+ pins = "gpio_pwrctrl2"; -+ function = "pin_fun4"; -+ }; -+ -+ rk806_dvs2_gpio: rk806_dvs2_gpio { -+ pins = "gpio_pwrctrl2"; -+ function = "pin_fun5"; -+ }; -+ -+ rk806_dvs3_null: rk806_dvs3_null { -+ pins = "gpio_pwrctrl3"; -+ function = "pin_fun0"; -+ }; -+ -+ rk806_dvs3_slp: rk806_dvs3_slp { -+ pins = "gpio_pwrctrl3"; -+ function = "pin_fun1"; -+ }; -+ -+ rk806_dvs3_pwrdn: rk806_dvs3_pwrdn { -+ pins = "gpio_pwrctrl3"; -+ function = "pin_fun2"; -+ }; -+ -+ rk806_dvs3_rst: rk806_dvs3_rst { -+ pins = "gpio_pwrctrl3"; -+ function = "pin_fun3"; -+ }; -+ -+ rk806_dvs3_dvs: rk806_dvs3_dvs { -+ pins = "gpio_pwrctrl3"; -+ function = "pin_fun4"; -+ }; -+ -+ rk806_dvs3_gpio: rk806_dvs3_gpio { -+ pins = "gpio_pwrctrl3"; -+ function = "pin_fun5"; -+ }; -+ -+ regulators { -+ vdd_gpu_s0: vdd_gpu_mem_s0: dcdc-reg1 { -+ regulator-name = "vdd_gpu_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <550000>; -+ regulator-max-microvolt = <950000>; -+ regulator-ramp-delay = <12500>; -+ regulator-enable-ramp-delay = <400>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdd_cpu_lit_s0: vdd_cpu_lit_mem_s0: dcdc-reg2 { -+ regulator-name = "vdd_cpu_lit_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <550000>; -+ regulator-max-microvolt = <950000>; -+ regulator-ramp-delay = <12500>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdd_log_s0: dcdc-reg3 { -+ regulator-name = "vdd_log_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <675000>; -+ regulator-max-microvolt = <750000>; -+ regulator-ramp-delay = <12500>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ regulator-suspend-microvolt = <750000>; -+ }; -+ }; -+ -+ vdd_vdenc_s0: dcdc-reg4 { -+ regulator-name = "vdd_vdenc_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <550000>; -+ regulator-max-microvolt = <950000>; -+ regulator-init-microvolt = <750000>; -+ regulator-ramp-delay = <12500>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ -+ }; -+ -+ vdd_ddr_s0: dcdc-reg5 { -+ regulator-name = "vdd_ddr_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <675000>; -+ regulator-max-microvolt = <950000>; -+ regulator-ramp-delay = <12500>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ regulator-suspend-microvolt = <850000>; -+ }; -+ -+ }; -+ -+ vdd2_ddr_s3: dcdc-reg6 { -+ regulator-name = "vdd2_ddr_s3"; -+ regulator-always-on; -+ regulator-boot-on; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vcc_2v0_pldo_s3: dcdc-reg7 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <2000000>; -+ regulator-max-microvolt = <2000000>; -+ regulator-name = "vdd_2v0_pldo_s3"; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <2000000>; -+ }; -+ }; -+ -+ vcc_3v3_s3: dcdc-reg8 { -+ regulator-name = "vcc_3v3_s3"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <3300000>; -+ }; -+ }; -+ -+ vddq_ddr_s0: dcdc-reg9 { -+ regulator-name = "vddq_ddr_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_1v8_s3: dcdc-reg10 { -+ regulator-name = "vcc_1v8_s3"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ avcc_1v8_s0: pldo-reg1 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-name = "avcc_1v8_s0"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_1v8_s0: pldo-reg2 { -+ regulator-name = "vcc_1v8_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ avdd_1v2_s0: pldo-reg3 { -+ regulator-name = "avdd_1v2_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1200000>; -+ regulator-max-microvolt = <1200000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_3v3_s0: pldo-reg4 { -+ regulator-name = "vcc_3v3_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vccio_sd_s0: pldo-reg5 { -+ regulator-name = "vccio_sd_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ pldo6_s3: pldo-reg6 { -+ regulator-name = "pldo6_s3"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ vdd_0v75_s3: nldo-reg1 { -+ regulator-name = "vdd_0v75_s3"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <750000>; -+ regulator-max-microvolt = <750000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <750000>; -+ }; -+ }; -+ -+ vdd_ddr_pll_s0: nldo-reg2 { -+ regulator-name = "vdd_ddr_pll_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <850000>; -+ regulator-max-microvolt = <850000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ regulator-suspend-microvolt = <850000>; -+ }; -+ }; -+ -+ avdd_0v75_s0: nldo-reg3 { -+ regulator-name = "avdd_0v75_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <750000>; -+ regulator-max-microvolt = <750000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdd_0v85_s0: nldo-reg4 { -+ regulator-name = "vdd_0v85_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <850000>; -+ regulator-max-microvolt = <850000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdd_0v75_s0: nldo-reg5 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <750000>; -+ regulator-max-microvolt = <750000>; -+ regulator-name = "vdd_0v75_s0"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ }; -+ }; -+}; -+ -+&mdio0 { -+ rgmii_phy: ethernet-phy@0 { -+ compatible = "ethernet-phy-ieee802.3-c22"; -+ reg = <0x0>; /* 0 for KSZ9031RNX */ -+ }; -+}; -+ -+&pinctrl { -+ dp { -+ dp1_hpd: dp1-hpd { -+ rockchip,pins = <1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ pcie2 { -+ pcie2_0_rst: pcie2-0-rst { -+ rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ pcie3 { -+ pcie3_reset: pcie3-reset { -+ rockchip,pins = <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ eth_phy { -+ eth_phy_reset: eth-phy-reset { -+ rockchip,pins = <3 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+}; -+ -+&u2phy0 { -+ status = "okay"; -+}; -+ -+&u2phy0_otg { -+ status = "okay"; -+}; -+ -+&u2phy1 { -+ status = "okay"; -+}; -+ -+&u2phy1_otg { -+ status = "okay"; -+}; -+ -+&u2phy2 { -+ status = "okay"; -+}; -+ -+&u2phy2_host { -+ phy-supply = <&vcc5v0_host>; -+ status = "okay"; -+}; -+ -+&u2phy3 { -+ status = "okay"; -+}; -+ -+&u2phy3_host { -+ phy-supply = <&vcc5v0_host>; -+ status = "okay"; -+}; -+ -+&uart2 { -+ pinctrl-0 = <&uart2m0_xfer>; -+ status = "okay"; -+}; -+ -+&usb_host0_ehci { -+ status = "okay"; -+}; -+ -+&usb_host0_ohci { -+ status = "okay"; -+}; -+ -+&usb_host1_ehci { -+ status = "okay"; -+}; -+ -+&usb_host1_ohci { -+ status = "okay"; -+}; -+ -+&usbdp_phy0 { -+ status = "okay"; -+}; -+ -+/*&usbdp_phy0_dp { -+ status = "okay"; -+}; -+ -+&usbdp_phy0_u3 { -+ status = "okay"; -+};*/ -+ -+&usbdp_phy1 { -+ status = "okay"; -+}; -+ -+/*&usbdp_phy1_u3 { -+ status = "okay"; -+};*/ -+ -+&usb_host0_xhci { -+ dr_mode = "host"; -+ status = "okay"; -+}; -+ -+&usb_host1_xhci { -+ dr_mode = "host"; -+ status = "okay"; -+}; -+ -+&vop_mmu { -+ status = "okay"; -+}; -+ -+&vop { -+ status = "okay"; -+}; -+ -+&vp0 { -+ vp0_out_hdmi1: endpoint@ROCKCHIP_VOP2_EP_HDMI1 { -+ reg = <ROCKCHIP_VOP2_EP_HDMI1>; -+ remote-endpoint = <&hdmi1_in_vp0>; -+ }; -+}; -+ -+/*&vp2 { -+ vp2_out_hdmi0: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { -+ reg = <ROCKCHIP_VOP2_EP_HDMI0>; -+ remote-endpoint = <&hdmi0_in_vp2>; -+ }; -+};*/ -+ -+&dsi1 { -+ status = "okay"; -+ rockchip,lane-rate = <972000>; -+ -+ panel { -+ compatible = "jdi,lt070me05000"; -+ reg = <0>; -+ -+ // reset is driven by rp2040 -+ // dcdc en is also driven by rp2040 -+ // actually backlight enable -+ enable-gpios = <&gpio2 RK_PB5 GPIO_ACTIVE_HIGH>; -+ no-eot-hfp-hbp-hsa; -+ -+ port { -+ mipi_panel_in: endpoint { -+ remote-endpoint = <&dsi1_out_panel>; -+ }; -+ }; -+ }; -+}; -+ -+&dsi1_in { -+ dsi1_in_vp2: endpoint { -+ remote-endpoint = <&vp2_out_dsi1>; -+ }; -+}; -+ -+&dsi1_out { -+ dsi1_out_panel: endpoint { -+ remote-endpoint = <&mipi_panel_in>; -+ }; -+}; -+ -+&vp2 { -+ assigned-clocks = <&cru DCLK_VOP2_SRC>; -+ assigned-clock-parents = <&cru PLL_V0PLL>; -+ -+ vp2_out_dsi1: endpoint@ROCKCHIP_VOP2_EP_MIPI1 { -+ reg = <ROCKCHIP_VOP2_EP_MIPI1>; -+ remote-endpoint = <&dsi1_in_vp2>; -+ }; -+}; -+ -+&mipidcphy1 { -+ status = "okay"; -+}; -Index: linux/arch/arm64/boot/dts/rockchip/rk3588-mnt-reform-next.dts -=================================================================== ---- /dev/null -+++ linux/arch/arm64/boot/dts/rockchip/rk3588-mnt-reform-next.dts -@@ -0,0 +1,993 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Copyright (c) 2021 Rockchip Electronics Co., Ltd. -+ * Copyright (c) 2024 MNT Research GmbH -+ * -+ */ -+ -+/dts-v1/; -+ -+#include <dt-bindings/gpio/gpio.h> -+#include <dt-bindings/input/input.h> -+#include <dt-bindings/pinctrl/rockchip.h> -+#include <dt-bindings/usb/pd.h> -+#include <dt-bindings/soc/rockchip,vop2.h> -+#include "rk3588.dtsi" -+ -+/ { -+ model = "MNT Reform Next with RCORE RK3588 Module"; -+ compatible = "mntre,reform-next-rcore", "firefly,icore3588q", "rockchip,rk3588"; -+ -+ aliases { -+ ethernet0 = &gmac0; -+ serial2 = &uart2; -+ mmc0 = &sdhci; -+ mmc1 = &sdmmc; -+ }; -+ -+ chosen { -+ stdout-path = "serial2:1500000n8"; -+ }; -+ -+ analog-sound { -+ compatible = "audio-graph-card"; -+ label = "rk3588-tlv320aic3100"; -+ -+ widgets = -+ "Headphone", "Headphone Jack", -+ "Microphone", "Microphone Jack", -+ "Speaker", "Speaker"; -+ -+ routing = -+ "MIC1RP", "MICBIAS", -+ "MIC1RP", "Microphone Jack", -+ "Headphone Jack", "HPR", -+ "Speaker", "SPK"; -+ -+ dais = <&i2s0_8ch_p0>; -+ }; -+ -+ backlight: backlight { -+ compatible = "pwm-backlight"; -+ pwms = <&pwm8 0 10000 0>; -+ enable-gpios = <&gpio2 RK_PB5 GPIO_ACTIVE_HIGH>; -+ brightness-levels = <0 8 16 32 64 128 160 200 255>; -+ default-brightness-level = <128>; -+ }; -+ -+ gmac0_clkin: external-gmac0-clock { -+ compatible = "fixed-clock"; -+ clock-frequency = <125000000>; -+ clock-output-names = "gmac0_clkin"; -+ #clock-cells = <0>; -+ }; -+ -+ pcie30_avdd1v8: pcie30-avdd1v8 { -+ compatible = "regulator-fixed"; -+ regulator-name = "pcie30_avdd1v8"; -+ regulator-boot-on; -+ regulator-always-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ vin-supply = <&avcc_1v8_s0>; -+ }; -+ -+ pcie30_avdd0v75: pcie30-avdd0v75 { -+ compatible = "regulator-fixed"; -+ regulator-name = "pcie30_avdd0v75"; -+ regulator-boot-on; -+ regulator-always-on; -+ regulator-min-microvolt = <750000>; -+ regulator-max-microvolt = <750000>; -+ vin-supply = <&avdd_0v75_s0>; -+ }; -+ -+ vcc12v_dcin: vcc12v-dcin-regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc12v_dcin"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <12000000>; -+ regulator-max-microvolt = <12000000>; -+ }; -+ -+ vcc_1v1_nldo_s3: vcc-1v1-nldo-s3 { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc_1v1_nldo_s3"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1100000>; -+ regulator-max-microvolt = <1100000>; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+ -+ vcc3v3_pcie30: vcc3v3-pcie30 { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc3v3_pcie30"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-boot-on; -+ regulator-always-on; -+ vin-supply = <&vcc12v_dcin>; -+ }; -+ -+ vcc5v0_host: vcc5v0-host { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc5v0_host"; -+ regulator-boot-on; -+ regulator-always-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ }; -+ -+ 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>; -+ }; -+}; -+ -+&combphy0_ps { -+ status = "okay"; -+}; -+ -+&combphy1_ps { -+ status = "okay"; -+}; -+ -+&combphy2_psu { -+ status = "okay"; -+}; -+ -+&cpu_b0 { -+ cpu-supply = <&vdd_cpu_big0_s0>; -+ mem-supply = <&vdd_cpu_big0_s0>; -+}; -+ -+&cpu_b1 { -+ cpu-supply = <&vdd_cpu_big0_s0>; -+ mem-supply = <&vdd_cpu_big0_s0>; -+}; -+ -+&cpu_b2 { -+ cpu-supply = <&vdd_cpu_big1_s0>; -+ mem-supply = <&vdd_cpu_big1_s0>; -+}; -+ -+&cpu_b3 { -+ cpu-supply = <&vdd_cpu_big1_s0>; -+ mem-supply = <&vdd_cpu_big1_s0>; -+}; -+ -+&cpu_l0 { -+ cpu-supply = <&vdd_cpu_lit_s0>; -+ mem-supply = <&vdd_cpu_lit_mem_s0>; -+}; -+ -+&cpu_l1 { -+ cpu-supply = <&vdd_cpu_lit_s0>; -+ mem-supply = <&vdd_cpu_lit_mem_s0>; -+}; -+ -+&cpu_l2 { -+ cpu-supply = <&vdd_cpu_lit_s0>; -+ mem-supply = <&vdd_cpu_lit_mem_s0>; -+}; -+ -+&cpu_l3 { -+ cpu-supply = <&vdd_cpu_lit_s0>; -+ mem-supply = <&vdd_cpu_lit_mem_s0>; -+}; -+ -+&display_subsystem { -+ clocks = <&hdptxphy_hdmi0>, <&hdptxphy_hdmi1>; -+ clock-names = "hdmi0_phy_pll", "hdmi1_phy_pll"; -+}; -+ -+&gmac0 { -+ clock_in_out = "output"; -+ phy-handle = <&rgmii_phy>; -+ phy-mode = "rgmii-id"; -+ pinctrl-0 = <&gmac0_miim -+ &gmac0_tx_bus2 -+ &gmac0_rx_bus2 -+ &gmac0_rgmii_clk -+ &gmac0_rgmii_bus -+ &gmac0_clkinout -+ ð_phy_reset>; -+ pinctrl-names = "default"; -+ -+ /* resetting in the driver is not reliable, -+ so we do it in reform-hw-setup -+ until we have enough test data to move -+ it to u-boot */ -+ -+ /*snps,reset-gpio = <&gpio3 RK_PC7 GPIO_ACTIVE_LOW>; -+ snps,reset-active-low; -+ snps,reset-delays-us = <0 20000 100000>;*/ -+ -+ status = "okay"; -+}; -+ -+&gpu { -+ mali-supply = <&vdd_gpu_s0>; -+ sram-supply = <&vdd_gpu_mem_s0>; -+ status = "okay"; -+}; -+ -+&hdmi0 { -+ enable-gpios = <&gpio4 RK_PA0 GPIO_ACTIVE_HIGH>; -+ status = "okay"; -+}; -+ -+&hdmi0_in { -+ hdmi0_in_vp2: endpoint { -+ remote-endpoint = <&vp2_out_hdmi0>; -+ }; -+}; -+ -+&hdptxphy_hdmi0 { -+ status = "okay"; -+}; -+ -+&hdmi1 { -+ //enable-gpios = <&gpio4 RK_PA1 GPIO_ACTIVE_HIGH>; // D-1 -+ enable-gpios = <&gpio4 RK_PB4 GPIO_ACTIVE_HIGH>; // D-2 -+ status = "okay"; -+}; -+ -+&hdmi1_in { -+ hdmi1_in_vp0: endpoint { -+ remote-endpoint = <&vp0_out_hdmi1>; -+ }; -+}; -+ -+&hdptxphy_hdmi1 { -+ status = "okay"; -+}; -+ -+&i2c0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c0m2_xfer>; -+ status = "okay"; -+ -+ vdd_cpu_big0_s0: vdd_cpu_big0_mem_s0: rk8602@42 { -+ compatible = "rockchip,rk8602"; -+ reg = <0x42>; -+ -+ vin-supply = <&vcc5v0_sys>; -+ fcs,suspend-voltage-selector = <1>; -+ rockchip,suspend-voltage-selector = <1>; -+ -+ regulator-compatible = "rk860x-reg"; -+ regulator-name = "vdd_cpu_big0_s0"; -+ regulator-min-microvolt = <0x86470>; -+ regulator-max-microvolt = <0x100590>; -+ regulator-ramp-delay = <0x8fc>; -+ regulator-boot-on; -+ regulator-always-on; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdd_cpu_big1_s0: vdd_cpu_big1_mem_s0: rk8603@43 { -+ compatible = "rockchip,rk8602", "rockchip,rk8603"; -+ reg = <0x43>; -+ -+ vin-supply = <&vcc5v0_sys>; -+ fcs,suspend-voltage-selector = <1>; -+ rockchip,suspend-voltage-selector = <1>; -+ -+ regulator-compatible = "rk860x-reg"; -+ regulator-name = "vdd_cpu_big1_s0"; -+ regulator-min-microvolt = <550000>; -+ regulator-max-microvolt = <1050000>; -+ regulator-ramp-delay = <2300>; -+ regulator-boot-on; -+ regulator-always-on; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+}; -+ -+&i2c1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c1m2_xfer>; -+ status = "okay"; -+ -+ vdd_npu_s0: vdd_npu_mem_s0: regulator@42 { -+ compatible = "rockchip,rk8602"; -+ reg = <0x42>; -+ fcs,suspend-voltage-selector = <1>; -+ regulator-name = "vdd_npu_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <550000>; -+ regulator-max-microvolt = <950000>; -+ regulator-ramp-delay = <2300>; -+ vin-supply = <&vcc5v0_sys>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+}; -+ -+&i2c6 { -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c6m0_xfer>; -+ -+ tlv320aic3100: codec@18 { -+ compatible = "ti,tlv320aic3100"; -+ reg = <0x18>; -+ clocks = <&cru I2S0_8CH_MCLKOUT>; -+ clock-names = "mclk"; -+ ai31xx-micbias-vg = <2>; -+ #sound-dai-cells = <0>; -+ -+ HPVDD-supply = <&vcc_3v3_s3>; -+ SPRVDD-supply = <&vcc5v0_host>; -+ SPLVDD-supply = <&vcc5v0_host>; -+ AVDD-supply = <&vcc_3v3_s3>; -+ IOVDD-supply = <&vcc_3v3_s3>; -+ DVDD-supply = <&vcc_1v8_s3>; -+ -+ status = "okay"; -+ -+ port { -+ tlv320aic3100_p0: endpoint { -+ remote-endpoint = <&i2s0_8ch_p0_0>; -+ }; -+ }; -+ }; -+ -+ rtc@68 { -+ compatible = "nxp,pcf8523"; -+ reg = <0x68>; -+ }; -+}; -+ -+&i2s0_8ch { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2s0_lrck -+ &i2s0_mclk -+ &i2s0_sclk -+ &i2s0_sdi0 -+ &i2s0_sdo0>; -+ status = "okay"; -+ -+ i2s0_8ch_p0: port { -+ i2s0_8ch_p0_0: endpoint { -+ dai-format = "i2s"; -+ remote-endpoint = <&tlv320aic3100_p0>; -+ }; -+ }; -+}; -+ -+&pcie2x1l2 { -+ reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>; -+ pinctrl-0 = <&pcie2_0_rst>; -+ status = "okay"; -+}; -+ -+/*&pcie2x1l1 { -+ reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_LOW>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie2_1_rst>; -+ status = "okay"; -+};*/ -+ -+&pcie30phy { -+ status = "okay"; -+}; -+ -+&pcie3x4 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie3_reset>; -+ reset-gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_HIGH>; -+ num-lanes = <4>; -+ vpcie3v3-supply = <&vcc3v3_pcie30>; -+ status = "okay"; -+}; -+ -+&i2c3 { -+ status = "okay"; -+}; -+ -+&pwm8 { -+ pinctrl-0 = <&pwm8m2_pins>; -+ status = "okay"; -+}; -+ -+&saradc { -+ vref-supply = <&avcc_1v8_s0>; -+ status = "okay"; -+}; -+ -+&tsadc { -+ status = "okay"; -+}; -+ -+&sdhci { -+ bus-width = <8>; -+ no-sdio; -+ no-sd; -+ non-removable; -+ max-frequency = <150000000>; -+ mmc-hs400-1_8v; -+ mmc-hs400-enhanced-strobe; -+ status = "okay"; -+}; -+ -+&sdmmc { -+ bus-width = <4>; -+ //max-frequency = <48000000>; -+ max-frequency = <40000000>; -+ no-sdio; -+ no-mmc; -+ no-1-8-v; -+ cap-sd-highspeed; -+ vqmmc-supply = <&vcc3v3_pcie30>; -+ vmmc-supply = <&vcc3v3_pcie30>; -+ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; -+ disable-wp; -+ status = "okay"; -+}; -+ -+&spi1 { -+ status = "okay"; -+ assigned-clocks = <&cru CLK_SPI1>; -+ assigned-clock-rates = <200000000>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi1m2_cs0 &spi1m2_pins>; -+ num-cs = <1>; -+ -+ spidev@0 { -+ compatible = "mntre,lpc11u24"; -+ spi-max-frequency = <1000000>; -+ reg = <0>; -+ }; -+}; -+ -+&spi2 { -+ status = "okay"; -+ assigned-clocks = <&cru CLK_SPI2>; -+ assigned-clock-rates = <200000000>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>; -+ num-cs = <1>; -+ -+ rk806single: pmic@0 { -+ compatible = "rockchip,rk806"; -+ spi-max-frequency = <1000000>; -+ reg = <0x0>; -+ -+ interrupt-parent = <&gpio0>; -+ interrupts = <7 IRQ_TYPE_LEVEL_LOW>; -+ -+ pinctrl-names = "default", "pmic-power-off"; -+ pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>, -+ <&rk806_dvs2_null>, <&rk806_dvs3_null>; -+ pinctrl-1 = <&rk806_dvs1_pwrdn>; -+ -+ /* TODO: missing some thresholds */ -+ -+ pmic-reset-func = <1>; -+ -+ vcc1-supply = <&vcc5v0_sys>; -+ vcc2-supply = <&vcc5v0_sys>; -+ vcc3-supply = <&vcc5v0_sys>; -+ vcc4-supply = <&vcc5v0_sys>; -+ vcc5-supply = <&vcc5v0_sys>; -+ vcc6-supply = <&vcc5v0_sys>; -+ vcc7-supply = <&vcc5v0_sys>; -+ vcc8-supply = <&vcc5v0_sys>; -+ vcc9-supply = <&vcc5v0_sys>; -+ vcc10-supply = <&vcc5v0_sys>; -+ vcc11-supply = <&vcc_2v0_pldo_s3>; -+ vcc12-supply = <&vcc5v0_sys>; -+ vcc13-supply = <&vcc_1v1_nldo_s3>; -+ vcc14-supply = <&vcc_1v1_nldo_s3>; -+ vcca-supply = <&vcc5v0_sys>; -+ -+ #gpio-cells = <2>; -+ gpio-controller; -+ -+ rk806_dvs1_null: dvs1-null-pins { -+ pins = "gpio_pwrctrl2"; -+ function = "pin_fun0"; -+ }; -+ -+ rk806_dvs1_slp: rk806_dvs1_slp { -+ pins = "gpio_pwrctrl1"; -+ function = "pin_fun1"; -+ }; -+ -+ rk806_dvs1_pwrdn: rk806_dvs1_pwrdn { -+ pins = "gpio_pwrctrl1"; -+ function = "pin_fun2"; -+ }; -+ -+ rk806_dvs1_rst: rk806_dvs1_rst { -+ pins = "gpio_pwrctrl1"; -+ function = "pin_fun3"; -+ }; -+ -+ rk806_dvs2_null: rk806_dvs2_null { -+ pins = "gpio_pwrctrl2"; -+ function = "pin_fun0"; -+ }; -+ -+ rk806_dvs2_slp: rk806_dvs2_slp { -+ pins = "gpio_pwrctrl2"; -+ function = "pin_fun1"; -+ }; -+ -+ rk806_dvs2_pwrdn: rk806_dvs2_pwrdn { -+ pins = "gpio_pwrctrl2"; -+ function = "pin_fun2"; -+ }; -+ -+ rk806_dvs2_rst: rk806_dvs2_rst { -+ pins = "gpio_pwrctrl2"; -+ function = "pin_fun3"; -+ }; -+ -+ rk806_dvs2_dvs: rk806_dvs2_dvs { -+ pins = "gpio_pwrctrl2"; -+ function = "pin_fun4"; -+ }; -+ -+ rk806_dvs2_gpio: rk806_dvs2_gpio { -+ pins = "gpio_pwrctrl2"; -+ function = "pin_fun5"; -+ }; -+ -+ rk806_dvs3_null: rk806_dvs3_null { -+ pins = "gpio_pwrctrl3"; -+ function = "pin_fun0"; -+ }; -+ -+ rk806_dvs3_slp: rk806_dvs3_slp { -+ pins = "gpio_pwrctrl3"; -+ function = "pin_fun1"; -+ }; -+ -+ rk806_dvs3_pwrdn: rk806_dvs3_pwrdn { -+ pins = "gpio_pwrctrl3"; -+ function = "pin_fun2"; -+ }; -+ -+ rk806_dvs3_rst: rk806_dvs3_rst { -+ pins = "gpio_pwrctrl3"; -+ function = "pin_fun3"; -+ }; -+ -+ rk806_dvs3_dvs: rk806_dvs3_dvs { -+ pins = "gpio_pwrctrl3"; -+ function = "pin_fun4"; -+ }; -+ -+ rk806_dvs3_gpio: rk806_dvs3_gpio { -+ pins = "gpio_pwrctrl3"; -+ function = "pin_fun5"; -+ }; -+ -+ regulators { -+ vdd_gpu_s0: vdd_gpu_mem_s0: dcdc-reg1 { -+ regulator-name = "vdd_gpu_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <550000>; -+ regulator-max-microvolt = <950000>; -+ regulator-ramp-delay = <12500>; -+ regulator-enable-ramp-delay = <400>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdd_cpu_lit_s0: vdd_cpu_lit_mem_s0: dcdc-reg2 { -+ regulator-name = "vdd_cpu_lit_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <550000>; -+ regulator-max-microvolt = <950000>; -+ regulator-ramp-delay = <12500>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdd_log_s0: dcdc-reg3 { -+ regulator-name = "vdd_log_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <675000>; -+ regulator-max-microvolt = <750000>; -+ regulator-ramp-delay = <12500>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ regulator-suspend-microvolt = <750000>; -+ }; -+ }; -+ -+ vdd_vdenc_s0: dcdc-reg4 { -+ regulator-name = "vdd_vdenc_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <550000>; -+ regulator-max-microvolt = <950000>; -+ regulator-init-microvolt = <750000>; -+ regulator-ramp-delay = <12500>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ -+ }; -+ -+ vdd_ddr_s0: dcdc-reg5 { -+ regulator-name = "vdd_ddr_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <675000>; -+ regulator-max-microvolt = <950000>; -+ regulator-ramp-delay = <12500>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ regulator-suspend-microvolt = <850000>; -+ }; -+ -+ }; -+ -+ vdd2_ddr_s3: dcdc-reg6 { -+ regulator-name = "vdd2_ddr_s3"; -+ regulator-always-on; -+ regulator-boot-on; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vcc_2v0_pldo_s3: dcdc-reg7 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <2000000>; -+ regulator-max-microvolt = <2000000>; -+ regulator-name = "vdd_2v0_pldo_s3"; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <2000000>; -+ }; -+ }; -+ -+ vcc_3v3_s3: dcdc-reg8 { -+ regulator-name = "vcc_3v3_s3"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <3300000>; -+ }; -+ }; -+ -+ vddq_ddr_s0: dcdc-reg9 { -+ regulator-name = "vddq_ddr_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_1v8_s3: dcdc-reg10 { -+ regulator-name = "vcc_1v8_s3"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ avcc_1v8_s0: pldo-reg1 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-name = "avcc_1v8_s0"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_1v8_s0: pldo-reg2 { -+ regulator-name = "vcc_1v8_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ avdd_1v2_s0: pldo-reg3 { -+ regulator-name = "avdd_1v2_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1200000>; -+ regulator-max-microvolt = <1200000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_3v3_s0: pldo-reg4 { -+ regulator-name = "vcc_3v3_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vccio_sd_s0: pldo-reg5 { -+ regulator-name = "vccio_sd_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ pldo6_s3: pldo-reg6 { -+ regulator-name = "pldo6_s3"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ vdd_0v75_s3: nldo-reg1 { -+ regulator-name = "vdd_0v75_s3"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <750000>; -+ regulator-max-microvolt = <750000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <750000>; -+ }; -+ }; -+ -+ vdd_ddr_pll_s0: nldo-reg2 { -+ regulator-name = "vdd_ddr_pll_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <850000>; -+ regulator-max-microvolt = <850000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ regulator-suspend-microvolt = <850000>; -+ }; -+ }; -+ -+ avdd_0v75_s0: nldo-reg3 { -+ regulator-name = "avdd_0v75_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <750000>; -+ regulator-max-microvolt = <750000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdd_0v85_s0: nldo-reg4 { -+ regulator-name = "vdd_0v85_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <850000>; -+ regulator-max-microvolt = <850000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdd_0v75_s0: nldo-reg5 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <750000>; -+ regulator-max-microvolt = <750000>; -+ regulator-name = "vdd_0v75_s0"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ }; -+ }; -+}; -+ -+&mdio0 { -+ rgmii_phy: ethernet-phy@0 { -+ compatible = "ethernet-phy-ieee802.3-c22"; -+ reg = <0x0>; /* 0 for KSZ9031RNX */ -+ }; -+}; -+ -+&pinctrl { -+ dp { -+ dp1_hpd: dp1-hpd { -+ rockchip,pins = <1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ pcie2 { -+ pcie2_0_rst: pcie2-0-rst { -+ rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ pcie3 { -+ pcie3_reset: pcie3-reset { -+ rockchip,pins = <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ eth_phy { -+ eth_phy_reset: eth-phy-reset { -+ rockchip,pins = <3 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+}; -+ -+&u2phy0 { -+ status = "okay"; -+}; -+ -+&u2phy0_otg { -+ status = "okay"; -+}; -+ -+&u2phy1 { -+ status = "okay"; -+}; -+ -+&u2phy1_otg { -+ status = "okay"; -+}; -+ -+&u2phy2 { -+ status = "okay"; -+}; -+ -+&u2phy2_host { -+ phy-supply = <&vcc5v0_host>; -+ status = "okay"; -+}; -+ -+&u2phy3 { -+ status = "okay"; -+}; -+ -+&u2phy3_host { -+ phy-supply = <&vcc5v0_host>; -+ status = "okay"; -+}; -+ -+&uart2 { -+ pinctrl-0 = <&uart2m0_xfer>; -+ status = "okay"; -+}; -+ -+&usb_host0_ehci { -+ status = "okay"; -+}; -+ -+&usb_host0_ohci { -+ status = "okay"; -+}; -+ -+&usb_host1_ehci { -+ status = "okay"; -+}; -+ -+&usb_host1_ohci { -+ status = "okay"; -+}; -+ -+&usbdp_phy0 { -+ status = "okay"; -+}; -+ -+/*&usbdp_phy0_dp { -+ status = "okay"; -+}; -+ -+&usbdp_phy0_u3 { -+ status = "okay"; -+};*/ -+ -+&usbdp_phy1 { -+ status = "okay"; -+}; -+ -+/*&usbdp_phy1_u3 { -+ status = "okay"; -+};*/ -+ -+&usb_host0_xhci { -+ dr_mode = "host"; -+ status = "okay"; -+}; -+ -+&usb_host1_xhci { -+ dr_mode = "host"; -+ status = "okay"; -+}; -+ -+&vop_mmu { -+ status = "okay"; -+}; -+ -+&vop { -+ status = "okay"; -+}; -+ -+&vp0 { -+ vp0_out_hdmi1: endpoint@ROCKCHIP_VOP2_EP_HDMI1 { -+ reg = <ROCKCHIP_VOP2_EP_HDMI1>; -+ remote-endpoint = <&hdmi1_in_vp0>; -+ }; -+}; -+ -+&vp2 { -+ vp2_out_hdmi0: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { -+ reg = <ROCKCHIP_VOP2_EP_HDMI0>; -+ remote-endpoint = <&hdmi0_in_vp2>; -+ }; -+}; -Index: linux/arch/arm64/boot/dts/rockchip/rk3588-mnt-reform2.dts -=================================================================== ---- /dev/null -+++ linux/arch/arm64/boot/dts/rockchip/rk3588-mnt-reform2.dts -@@ -0,0 +1,988 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Copyright (c) 2021 Rockchip Electronics Co., Ltd. -+ * Copyright (c) 2024 MNT Research GmbH -+ * -+ */ -+ -+/dts-v1/; -+ -+#include <dt-bindings/gpio/gpio.h> -+#include <dt-bindings/input/input.h> -+#include <dt-bindings/pinctrl/rockchip.h> -+#include <dt-bindings/usb/pd.h> -+#include <dt-bindings/soc/rockchip,vop2.h> -+#include "rk3588.dtsi" -+ -+/ { -+ model = "MNT Reform 2 with RCORE RK3588 Module"; -+ compatible = "mntre,reform2-rcore", "firefly,icore3588q", "rockchip,rk3588"; -+ -+ aliases { -+ ethernet0 = &gmac0; -+ serial2 = &uart2; -+ mmc0 = &sdhci; -+ mmc1 = &sdmmc; -+ }; -+ -+ chosen { -+ stdout-path = "serial2:1500000n8"; -+ }; -+ -+ analog-sound { -+ compatible = "audio-graph-card"; -+ label = "rk3588-wm8960"; -+ -+ widgets = -+ "Headphone", "Headphone Jack", -+ "Microphone", "Mic Jack", -+ "Speaker", "Ext Spk"; -+ -+ routing = -+ "Headphone Jack", "HP_L", -+ "Headphone Jack", "HP_R", -+ "Ext Spk", "SPK_LP", -+ "Ext Spk", "SPK_LN", -+ "Ext Spk", "SPK_RP", -+ "Ext Spk", "SPK_RN", -+ "LINPUT1", "Mic Jack", -+ "Mic Jack", "MICB"; -+ -+ dais = <&i2s0_8ch_p0>; -+ }; -+ -+ backlight: backlight { -+ compatible = "pwm-backlight"; -+ pwms = <&pwm8 0 10000 0>; -+ enable-gpios = <&gpio2 RK_PB5 GPIO_ACTIVE_HIGH>; -+ brightness-levels = <0 8 16 32 64 128 160 200 255>; -+ default-brightness-level = <128>; -+ }; -+ -+ gmac0_clkin: external-gmac0-clock { -+ compatible = "fixed-clock"; -+ clock-frequency = <125000000>; -+ clock-output-names = "gmac0_clkin"; -+ #clock-cells = <0>; -+ }; -+ -+ pcie30_avdd1v8: pcie30-avdd1v8 { -+ compatible = "regulator-fixed"; -+ regulator-name = "pcie30_avdd1v8"; -+ regulator-boot-on; -+ regulator-always-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ vin-supply = <&avcc_1v8_s0>; -+ }; -+ -+ pcie30_avdd0v75: pcie30-avdd0v75 { -+ compatible = "regulator-fixed"; -+ regulator-name = "pcie30_avdd0v75"; -+ regulator-boot-on; -+ regulator-always-on; -+ regulator-min-microvolt = <750000>; -+ regulator-max-microvolt = <750000>; -+ vin-supply = <&avdd_0v75_s0>; -+ }; -+ -+ vcc12v_dcin: vcc12v-dcin-regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc12v_dcin"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <12000000>; -+ regulator-max-microvolt = <12000000>; -+ }; -+ -+ vcc_1v1_nldo_s3: vcc-1v1-nldo-s3 { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc_1v1_nldo_s3"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1100000>; -+ regulator-max-microvolt = <1100000>; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+ -+ vcc3v3_pcie30: vcc3v3-pcie30 { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc3v3_pcie30"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-boot-on; -+ regulator-always-on; -+ vin-supply = <&vcc12v_dcin>; -+ }; -+ -+ vcc5v0_host: vcc5v0-host { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc5v0_host"; -+ regulator-boot-on; -+ regulator-always-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ }; -+ -+ 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>; -+ }; -+}; -+ -+&combphy0_ps { -+ status = "okay"; -+}; -+ -+&combphy1_ps { -+ status = "okay"; -+}; -+ -+&combphy2_psu { -+ status = "okay"; -+}; -+ -+&cpu_b0 { -+ cpu-supply = <&vdd_cpu_big0_s0>; -+ mem-supply = <&vdd_cpu_big0_s0>; -+}; -+ -+&cpu_b1 { -+ cpu-supply = <&vdd_cpu_big0_s0>; -+ mem-supply = <&vdd_cpu_big0_s0>; -+}; -+ -+&cpu_b2 { -+ cpu-supply = <&vdd_cpu_big1_s0>; -+ mem-supply = <&vdd_cpu_big1_s0>; -+}; -+ -+&cpu_b3 { -+ cpu-supply = <&vdd_cpu_big1_s0>; -+ mem-supply = <&vdd_cpu_big1_s0>; -+}; -+ -+&cpu_l0 { -+ cpu-supply = <&vdd_cpu_lit_s0>; -+ mem-supply = <&vdd_cpu_lit_mem_s0>; -+}; -+ -+&cpu_l1 { -+ cpu-supply = <&vdd_cpu_lit_s0>; -+ mem-supply = <&vdd_cpu_lit_mem_s0>; -+}; -+ -+&cpu_l2 { -+ cpu-supply = <&vdd_cpu_lit_s0>; -+ mem-supply = <&vdd_cpu_lit_mem_s0>; -+}; -+ -+&cpu_l3 { -+ cpu-supply = <&vdd_cpu_lit_s0>; -+ mem-supply = <&vdd_cpu_lit_mem_s0>; -+}; -+ -+&display_subsystem { -+ clocks = <&hdptxphy_hdmi0>, <&hdptxphy_hdmi1>; -+ clock-names = "hdmi0_phy_pll", "hdmi1_phy_pll"; -+}; -+ -+&gmac0 { -+ clock_in_out = "output"; -+ phy-handle = <&rgmii_phy>; -+ phy-mode = "rgmii-id"; -+ pinctrl-0 = <&gmac0_miim -+ &gmac0_tx_bus2 -+ &gmac0_rx_bus2 -+ &gmac0_rgmii_clk -+ &gmac0_rgmii_bus -+ &gmac0_clkinout -+ ð_phy_reset>; -+ pinctrl-names = "default"; -+ -+ /* resetting in the driver is not reliable, -+ so we do it in reform-hw-setup -+ until we have enough test data to move -+ it to u-boot */ -+ -+ /*snps,reset-gpio = <&gpio3 RK_PC7 GPIO_ACTIVE_LOW>; -+ snps,reset-active-low; -+ snps,reset-delays-us = <0 20000 100000>;*/ -+ -+ status = "okay"; -+}; -+ -+&gpu { -+ mali-supply = <&vdd_gpu_s0>; -+ sram-supply = <&vdd_gpu_mem_s0>; -+ status = "okay"; -+}; -+ -+&hdmi0 { -+ enable-gpios = <&gpio4 RK_PA0 GPIO_ACTIVE_HIGH>; -+ status = "okay"; -+}; -+ -+&hdmi0_in { -+ hdmi0_in_vp2: endpoint { -+ remote-endpoint = <&vp2_out_hdmi0>; -+ }; -+}; -+ -+&hdptxphy_hdmi0 { -+ status = "okay"; -+}; -+ -+&hdmi1 { -+ enable-gpios = <&gpio4 RK_PB4 GPIO_ACTIVE_HIGH>; -+ status = "okay"; -+}; -+ -+&hdmi1_in { -+ hdmi1_in_vp0: endpoint { -+ remote-endpoint = <&vp0_out_hdmi1>; -+ }; -+}; -+ -+&hdptxphy_hdmi1 { -+ status = "okay"; -+}; -+ -+&i2c0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c0m2_xfer>; -+ status = "okay"; -+ -+ vdd_cpu_big0_s0: vdd_cpu_big0_mem_s0: rk8602@42 { -+ compatible = "rockchip,rk8602"; -+ reg = <0x42>; -+ -+ vin-supply = <&vcc5v0_sys>; -+ fcs,suspend-voltage-selector = <1>; -+ rockchip,suspend-voltage-selector = <1>; -+ -+ regulator-compatible = "rk860x-reg"; -+ regulator-name = "vdd_cpu_big0_s0"; -+ regulator-min-microvolt = <0x86470>; -+ regulator-max-microvolt = <0x100590>; -+ regulator-ramp-delay = <0x8fc>; -+ regulator-boot-on; -+ regulator-always-on; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdd_cpu_big1_s0: vdd_cpu_big1_mem_s0: rk8603@43 { -+ compatible = "rockchip,rk8602", "rockchip,rk8603"; -+ reg = <0x43>; -+ -+ vin-supply = <&vcc5v0_sys>; -+ fcs,suspend-voltage-selector = <1>; -+ rockchip,suspend-voltage-selector = <1>; -+ -+ regulator-compatible = "rk860x-reg"; -+ regulator-name = "vdd_cpu_big1_s0"; -+ regulator-min-microvolt = <550000>; -+ regulator-max-microvolt = <1050000>; -+ regulator-ramp-delay = <2300>; -+ regulator-boot-on; -+ regulator-always-on; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+}; -+ -+&i2c1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c1m2_xfer>; -+ status = "okay"; -+ -+ vdd_npu_s0: vdd_npu_mem_s0: regulator@42 { -+ compatible = "rockchip,rk8602"; -+ reg = <0x42>; -+ fcs,suspend-voltage-selector = <1>; -+ regulator-name = "vdd_npu_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <550000>; -+ regulator-max-microvolt = <950000>; -+ regulator-ramp-delay = <2300>; -+ vin-supply = <&vcc5v0_sys>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+}; -+ -+&i2c6 { -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c6m0_xfer>; -+ -+ wm8960: codec@1a { -+ compatible = "wlf,wm8960"; -+ reg = <0x1a>; -+ clocks = <&cru I2S0_8CH_MCLKOUT>; -+ clock-names = "mclk"; -+ assigned-clocks = <&cru I2S0_8CH_MCLKOUT>; -+ assigned-clock-rates = <12288000>; -+ #sound-dai-cells = <0>; -+ -+ port { -+ wm8960_p0: endpoint { -+ remote-endpoint = <&i2s0_8ch_p0_0>; -+ }; -+ }; -+ }; -+ -+ rtc@68 { -+ compatible = "nxp,pcf8523"; -+ reg = <0x68>; -+ }; -+}; -+ -+&i2s0_8ch { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2s0_lrck -+ &i2s0_mclk -+ &i2s0_sclk -+ &i2s0_sdi0 -+ &i2s0_sdo0>; -+ status = "okay"; -+ -+ i2s0_8ch_p0: port { -+ i2s0_8ch_p0_0: endpoint { -+ dai-format = "i2s"; -+ mclk-fs = <256>; -+ remote-endpoint = <&wm8960_p0>; -+ }; -+ }; -+}; -+ -+&pcie2x1l2 { -+ reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>; -+ pinctrl-0 = <&pcie2_0_rst>; -+ status = "okay"; -+}; -+ -+/*&pcie2x1l1 { -+ reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_LOW>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie2_1_rst>; -+ status = "okay"; -+};*/ -+ -+&pcie30phy { -+ status = "okay"; -+}; -+ -+&pcie3x4 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie3_reset>; -+ reset-gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_HIGH>; -+ num-lanes = <1>; -+ vpcie3v3-supply = <&vcc3v3_pcie30>; -+ status = "okay"; -+}; -+ -+&i2c3 { -+ status = "okay"; -+}; -+ -+&pwm8 { -+ pinctrl-0 = <&pwm8m2_pins>; -+ status = "okay"; -+}; -+ -+&saradc { -+ vref-supply = <&avcc_1v8_s0>; -+ status = "okay"; -+}; -+ -+&tsadc { -+ status = "okay"; -+}; -+ -+&sdhci { -+ bus-width = <8>; -+ no-sdio; -+ no-sd; -+ non-removable; -+ max-frequency = <150000000>; -+ mmc-hs400-1_8v; -+ mmc-hs400-enhanced-strobe; -+ status = "okay"; -+}; -+ -+&sdmmc { -+ bus-width = <4>; -+ max-frequency = <40000000>; -+ no-sdio; -+ no-mmc; -+ no-1-8-v; -+ cap-sd-highspeed; -+ vqmmc-supply = <&vcc3v3_pcie30>; -+ vmmc-supply = <&vcc3v3_pcie30>; -+ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; -+ disable-wp; -+ status = "okay"; -+}; -+ -+&spi1 { -+ status = "okay"; -+ assigned-clocks = <&cru CLK_SPI1>; -+ assigned-clock-rates = <200000000>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi1m2_cs0 &spi1m2_pins>; -+ num-cs = <1>; -+ -+ spidev@0 { -+ compatible = "mntre,lpc11u24"; -+ spi-max-frequency = <1000000>; -+ reg = <0>; -+ }; -+}; -+ -+&spi2 { -+ status = "okay"; -+ assigned-clocks = <&cru CLK_SPI2>; -+ assigned-clock-rates = <200000000>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>; -+ num-cs = <1>; -+ -+ rk806single: pmic@0 { -+ compatible = "rockchip,rk806"; -+ spi-max-frequency = <1000000>; -+ reg = <0x0>; -+ -+ interrupt-parent = <&gpio0>; -+ interrupts = <7 IRQ_TYPE_LEVEL_LOW>; -+ -+ pinctrl-names = "default", "pmic-power-off"; -+ pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>, -+ <&rk806_dvs2_null>, <&rk806_dvs3_null>; -+ pinctrl-1 = <&rk806_dvs1_pwrdn>; -+ -+ /* TODO: missing some thresholds */ -+ -+ pmic-reset-func = <1>; -+ -+ vcc1-supply = <&vcc5v0_sys>; -+ vcc2-supply = <&vcc5v0_sys>; -+ vcc3-supply = <&vcc5v0_sys>; -+ vcc4-supply = <&vcc5v0_sys>; -+ vcc5-supply = <&vcc5v0_sys>; -+ vcc6-supply = <&vcc5v0_sys>; -+ vcc7-supply = <&vcc5v0_sys>; -+ vcc8-supply = <&vcc5v0_sys>; -+ vcc9-supply = <&vcc5v0_sys>; -+ vcc10-supply = <&vcc5v0_sys>; -+ vcc11-supply = <&vcc_2v0_pldo_s3>; -+ vcc12-supply = <&vcc5v0_sys>; -+ vcc13-supply = <&vcc_1v1_nldo_s3>; -+ vcc14-supply = <&vcc_1v1_nldo_s3>; -+ vcca-supply = <&vcc5v0_sys>; -+ -+ #gpio-cells = <2>; -+ gpio-controller; -+ -+ rk806_dvs1_null: dvs1-null-pins { -+ pins = "gpio_pwrctrl2"; -+ function = "pin_fun0"; -+ }; -+ -+ rk806_dvs1_slp: rk806_dvs1_slp { -+ pins = "gpio_pwrctrl1"; -+ function = "pin_fun1"; -+ }; -+ -+ rk806_dvs1_pwrdn: rk806_dvs1_pwrdn { -+ pins = "gpio_pwrctrl1"; -+ function = "pin_fun2"; -+ }; -+ -+ rk806_dvs1_rst: rk806_dvs1_rst { -+ pins = "gpio_pwrctrl1"; -+ function = "pin_fun3"; -+ }; -+ -+ rk806_dvs2_null: rk806_dvs2_null { -+ pins = "gpio_pwrctrl2"; -+ function = "pin_fun0"; -+ }; -+ -+ rk806_dvs2_slp: rk806_dvs2_slp { -+ pins = "gpio_pwrctrl2"; -+ function = "pin_fun1"; -+ }; -+ -+ rk806_dvs2_pwrdn: rk806_dvs2_pwrdn { -+ pins = "gpio_pwrctrl2"; -+ function = "pin_fun2"; -+ }; -+ -+ rk806_dvs2_rst: rk806_dvs2_rst { -+ pins = "gpio_pwrctrl2"; -+ function = "pin_fun3"; -+ }; -+ -+ rk806_dvs2_dvs: rk806_dvs2_dvs { -+ pins = "gpio_pwrctrl2"; -+ function = "pin_fun4"; -+ }; -+ -+ rk806_dvs2_gpio: rk806_dvs2_gpio { -+ pins = "gpio_pwrctrl2"; -+ function = "pin_fun5"; -+ }; -+ -+ rk806_dvs3_null: rk806_dvs3_null { -+ pins = "gpio_pwrctrl3"; -+ function = "pin_fun0"; -+ }; -+ -+ rk806_dvs3_slp: rk806_dvs3_slp { -+ pins = "gpio_pwrctrl3"; -+ function = "pin_fun1"; -+ }; -+ -+ rk806_dvs3_pwrdn: rk806_dvs3_pwrdn { -+ pins = "gpio_pwrctrl3"; -+ function = "pin_fun2"; -+ }; -+ -+ rk806_dvs3_rst: rk806_dvs3_rst { -+ pins = "gpio_pwrctrl3"; -+ function = "pin_fun3"; -+ }; -+ -+ rk806_dvs3_dvs: rk806_dvs3_dvs { -+ pins = "gpio_pwrctrl3"; -+ function = "pin_fun4"; -+ }; -+ -+ rk806_dvs3_gpio: rk806_dvs3_gpio { -+ pins = "gpio_pwrctrl3"; -+ function = "pin_fun5"; -+ }; -+ -+ regulators { -+ vdd_gpu_s0: vdd_gpu_mem_s0: dcdc-reg1 { -+ regulator-name = "vdd_gpu_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <550000>; -+ regulator-max-microvolt = <950000>; -+ regulator-ramp-delay = <12500>; -+ regulator-enable-ramp-delay = <400>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdd_cpu_lit_s0: vdd_cpu_lit_mem_s0: dcdc-reg2 { -+ regulator-name = "vdd_cpu_lit_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <550000>; -+ regulator-max-microvolt = <950000>; -+ regulator-ramp-delay = <12500>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdd_log_s0: dcdc-reg3 { -+ regulator-name = "vdd_log_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <675000>; -+ regulator-max-microvolt = <750000>; -+ regulator-ramp-delay = <12500>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ regulator-suspend-microvolt = <750000>; -+ }; -+ }; -+ -+ vdd_vdenc_s0: dcdc-reg4 { -+ regulator-name = "vdd_vdenc_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <550000>; -+ regulator-max-microvolt = <950000>; -+ regulator-init-microvolt = <750000>; -+ regulator-ramp-delay = <12500>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ -+ }; -+ -+ vdd_ddr_s0: dcdc-reg5 { -+ regulator-name = "vdd_ddr_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <675000>; -+ regulator-max-microvolt = <950000>; -+ regulator-ramp-delay = <12500>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ regulator-suspend-microvolt = <850000>; -+ }; -+ -+ }; -+ -+ vdd2_ddr_s3: dcdc-reg6 { -+ regulator-name = "vdd2_ddr_s3"; -+ regulator-always-on; -+ regulator-boot-on; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vcc_2v0_pldo_s3: dcdc-reg7 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <2000000>; -+ regulator-max-microvolt = <2000000>; -+ regulator-name = "vdd_2v0_pldo_s3"; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <2000000>; -+ }; -+ }; -+ -+ vcc_3v3_s3: dcdc-reg8 { -+ regulator-name = "vcc_3v3_s3"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <3300000>; -+ }; -+ }; -+ -+ vddq_ddr_s0: dcdc-reg9 { -+ regulator-name = "vddq_ddr_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_1v8_s3: dcdc-reg10 { -+ regulator-name = "vcc_1v8_s3"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ avcc_1v8_s0: pldo-reg1 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-name = "avcc_1v8_s0"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_1v8_s0: pldo-reg2 { -+ regulator-name = "vcc_1v8_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ avdd_1v2_s0: pldo-reg3 { -+ regulator-name = "avdd_1v2_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1200000>; -+ regulator-max-microvolt = <1200000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_3v3_s0: pldo-reg4 { -+ regulator-name = "vcc_3v3_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vccio_sd_s0: pldo-reg5 { -+ regulator-name = "vccio_sd_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ pldo6_s3: pldo-reg6 { -+ regulator-name = "pldo6_s3"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ vdd_0v75_s3: nldo-reg1 { -+ regulator-name = "vdd_0v75_s3"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <750000>; -+ regulator-max-microvolt = <750000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <750000>; -+ }; -+ }; -+ -+ vdd_ddr_pll_s0: nldo-reg2 { -+ regulator-name = "vdd_ddr_pll_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <850000>; -+ regulator-max-microvolt = <850000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ regulator-suspend-microvolt = <850000>; -+ }; -+ }; -+ -+ avdd_0v75_s0: nldo-reg3 { -+ regulator-name = "avdd_0v75_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <750000>; -+ regulator-max-microvolt = <750000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdd_0v85_s0: nldo-reg4 { -+ regulator-name = "vdd_0v85_s0"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <850000>; -+ regulator-max-microvolt = <850000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdd_0v75_s0: nldo-reg5 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <750000>; -+ regulator-max-microvolt = <750000>; -+ regulator-name = "vdd_0v75_s0"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ }; -+ }; -+}; -+ -+&mdio0 { -+ rgmii_phy: ethernet-phy@0 { -+ compatible = "ethernet-phy-ieee802.3-c22"; -+ reg = <0x0>; /* 0 for KSZ9031RNX */ -+ }; -+}; -+ -+&pinctrl { -+ dp { -+ dp1_hpd: dp1-hpd { -+ rockchip,pins = <1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ pcie2 { -+ pcie2_0_rst: pcie2-0-rst { -+ rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ pcie3 { -+ pcie3_reset: pcie3-reset { -+ rockchip,pins = <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ eth_phy { -+ eth_phy_reset: eth-phy-reset { -+ rockchip,pins = <3 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+}; -+ -+&u2phy0 { -+ status = "okay"; -+}; -+ -+&u2phy0_otg { -+ status = "okay"; -+}; -+ -+&u2phy1 { -+ status = "okay"; -+}; -+ -+&u2phy1_otg { -+ status = "okay"; -+}; -+ -+&u2phy2 { -+ status = "okay"; -+}; -+ -+&u2phy2_host { -+ phy-supply = <&vcc5v0_host>; -+ status = "okay"; -+}; -+ -+&u2phy3 { -+ status = "okay"; -+}; -+ -+&u2phy3_host { -+ phy-supply = <&vcc5v0_host>; -+ status = "okay"; -+}; -+ -+&uart2 { -+ pinctrl-0 = <&uart2m0_xfer>; -+ status = "okay"; -+}; -+ -+&usb_host0_ehci { -+ status = "okay"; -+}; -+ -+&usb_host0_ohci { -+ status = "okay"; -+}; -+ -+&usb_host1_ehci { -+ status = "okay"; -+}; -+ -+&usb_host1_ohci { -+ status = "okay"; -+}; -+ -+&usbdp_phy0 { -+ status = "okay"; -+}; -+ -+/*&usbdp_phy0_dp { -+ status = "okay"; -+}; -+ -+&usbdp_phy0_u3 { -+ status = "okay"; -+};*/ -+ -+&usbdp_phy1 { -+ status = "okay"; -+}; -+ -+/*&usbdp_phy1_u3 { -+ status = "okay"; -+};*/ -+ -+&usb_host0_xhci { -+ dr_mode = "host"; -+ status = "okay"; -+}; -+ -+&usb_host1_xhci { -+ dr_mode = "host"; -+ status = "okay"; -+}; -+ -+&vop_mmu { -+ status = "okay"; -+}; -+ -+&vop { -+ status = "okay"; -+}; -+ -+&vp0 { -+ vp0_out_hdmi1: endpoint@ROCKCHIP_VOP2_EP_HDMI1 { -+ reg = <ROCKCHIP_VOP2_EP_HDMI1>; -+ remote-endpoint = <&hdmi1_in_vp0>; -+ }; -+}; -+ -+&vp2 { -+ vp2_out_hdmi0: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { -+ reg = <ROCKCHIP_VOP2_EP_HDMI0>; -+ remote-endpoint = <&hdmi0_in_vp2>; -+ }; -+}; -Index: linux/arch/arm64/boot/dts/amlogic/meson-g12b-bananapi-cm4-mnt-reform2.dts -=================================================================== ---- linux.orig/arch/arm64/boot/dts/amlogic/meson-g12b-bananapi-cm4-mnt-reform2.dts -+++ linux/arch/arm64/boot/dts/amlogic/meson-g12b-bananapi-cm4-mnt-reform2.dts -@@ -79,10 +79,6 @@ - "LINPUT1", "Mic Jack", - "Mic Jack", "MICB"; - -- clocks = <&clkc CLKID_MPLL2>, -- <&clkc CLKID_MPLL0>, -- <&clkc CLKID_MPLL1>; -- - assigned-clocks = <&clkc CLKID_MPLL2>, - <&clkc CLKID_MPLL0>, - <&clkc CLKID_MPLL1>; -@@ -197,14 +193,18 @@ - enable-gpios = <&gpio 58 GPIO_ACTIVE_HIGH>; - brightness-levels = <0 32 64 128 160 200 255>; - default-brightness-level = <6>; -+ -+ status = "okay"; - }; - - panel { -- compatible = "innolux,n125hce-gn1"; -+ compatible = "innolux,n125hce-gn1-a311d", "simple-panel"; - power-supply = <®_main_3v3>; - backlight = <&backlight>; - no-hpd; - -+ status = "okay"; -+ - port { - panel_in: endpoint { - remote-endpoint = <&edp_bridge_out>; -@@ -217,6 +217,24 @@ - #clock-cells = <0>; - clock-frequency = <12288000>; - }; -+ -+ spi { -+ compatible = "spi-gpio"; -+ #address-cells = <0x1>; -+ ranges; -+ -+ sck-gpios = <&gpio_ao GPIOAO_5 0>; // GPIOAO_5 / GPIO7 -+ miso-gpios = <&gpio GPIOH_4 0>; // GPIOH_4 / GPIO5 -+ mosi-gpios = <&gpio_ao GPIOAO_10 0>; // GPIOAO_10 / GPIO6 -+ cs-gpios = <&gpio GPIOA_10 0>; // GPIOA_10 / GPIO4 -+ num-chipselects = <1>; -+ -+ spidev@0 { -+ compatible = "mntre,lpc11u24"; -+ spi-max-frequency = <1000000>; -+ reg = <0>; -+ }; -+ }; - }; - - &mipi_analog_dphy { -@@ -281,6 +299,10 @@ - status = "okay"; - }; - -+&i2c2 { -+ status = "okay"; -+}; -+ - &i2c3 { - status = "okay"; - -@@ -292,6 +314,7 @@ - vpll-supply = <®_main_1v8>; - vcca-supply = <®_main_1v2>; - vcc-supply = <®_main_1v2>; -+ burst-mode; - - ports { - #address-cells = <1>; -@@ -314,10 +337,6 @@ - }; - }; - }; --}; -- --&i2c2 { -- status = "okay"; - - wm8960: codec@1a { - compatible = "wlf,wm8960"; -Index: linux/arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2.dts -=================================================================== ---- linux.orig/arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2.dts -+++ linux/arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2.dts -@@ -1,69 +1,78 @@ - // SPDX-License-Identifier: (GPL-2.0+ OR MIT) -- - /* -- * Copyright 2019-2021 MNT Research GmbH -- * Copyright 2021 Lucas Stach <dev@lynxeye.de> -- */ -+* Copyright 2018 Boundary Devices -+* Copyright 2019-2021 MNT Research GmbH -+*/ - - /dts-v1/; - --#include "imx8mq-nitrogen-som.dtsi" -+#include "dt-bindings/input/input.h" -+#include "dt-bindings/pwm/pwm.h" -+#include "dt-bindings/usb/pd.h" -+#include "dt-bindings/gpio/gpio.h" -+#include "imx8mq.dtsi" - - / { - model = "MNT Reform 2"; -- compatible = "mntre,reform2", "boundary,imx8mq-nitrogen8m-som", "fsl,imx8mq"; -+ compatible = "boundary,imx8mq-nitrogen8m_som", "fsl,imx8mq"; - chassis-type = "laptop"; - -- backlight: backlight { -- compatible = "pwm-backlight"; -- pinctrl-names = "default"; -- pinctrl-0 = <&pinctrl_backlight>; -- pwms = <&pwm2 0 10000 0>; -- power-supply = <®_main_usb>; -- enable-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; -- brightness-levels = <0 32 64 128 160 200 255>; -- default-brightness-level = <6>; -+ chosen { -+ stdout-path = "serial0:115200n8"; - }; - -- panel { -- compatible = "innolux,n125hce-gn1"; -- power-supply = <®_main_3v3>; -- backlight = <&backlight>; -- no-hpd; -+ // 4GB of RAM -+ memory@40000000 { -+ device_type = "memory"; -+ reg = <0x00000000 0x40000000 0 0xc0000000>; // TODO: confirm what this means -+ }; - -- port { -- panel_in: endpoint { -- remote-endpoint = <&edp_bridge_out>; -- }; -- }; -+ reg_vref_0v9: regulator-vref-0v9 { -+ compatible = "regulator-fixed"; -+ regulator-name = "vref-0v9"; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <900000>; -+ regulator-always-on; - }; - -- pcie1_refclk: clock-pcie1-refclk { -- compatible = "fixed-clock"; -- #clock-cells = <0>; -- clock-frequency = <100000000>; -+ reg_vref_1v2: regulator-vref-1v2 { -+ compatible = "regulator-fixed"; -+ regulator-name = "vref-1v2"; -+ regulator-min-microvolt = <1200000>; -+ regulator-max-microvolt = <1200000>; -+ regulator-always-on; - }; - -- reg_main_5v: regulator-main-5v { -+ reg_vref_1v8: regulator-vref-1v8 { - compatible = "regulator-fixed"; -- regulator-name = "5V"; -- regulator-min-microvolt = <5000000>; -- regulator-max-microvolt = <5000000>; -+ regulator-name = "vref-1v8"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; - }; - -- reg_main_3v3: regulator-main-3v3 { -+ reg_vref_2v5: regulator-vref-2v5 { - compatible = "regulator-fixed"; -- regulator-name = "3V3"; -+ regulator-name = "vref-2v5"; -+ regulator-min-microvolt = <2500000>; -+ regulator-max-microvolt = <2500000>; -+ regulator-always-on; -+ }; -+ -+ reg_vref_3v3: regulator-vref-3v3 { -+ compatible = "regulator-fixed"; -+ regulator-name = "vref-3v3"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; -+ regulator-always-on; - }; - -- reg_main_usb: regulator-main-usb { -+ reg_vref_5v: regulator-vref-5v { - compatible = "regulator-fixed"; -- regulator-name = "USB_PWR"; -+ regulator-name = "vref-5v"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; -- vin-supply = <®_main_5v>; -+ regulator-always-on; - }; - - reg_main_1v8: regulator-main-1v8 { -@@ -71,7 +80,7 @@ - regulator-name = "1V8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; -- vin-supply = <®_main_3v3>; -+ vin-supply = <®_vref_3v3>; - }; - - reg_main_1v2: regulator-main-1v2 { -@@ -79,7 +88,28 @@ - regulator-name = "1V2"; - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <1200000>; -- vin-supply = <®_main_5v>; -+ vin-supply = <®_vref_5v>; -+ }; -+ -+ backlight: backlight { -+ compatible = "pwm-backlight"; -+ pwms = <&pwm2 0 10000 0>; -+ enable-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; -+ brightness-levels = <0 8 16 32 64 128 160 200 255>; -+ default-brightness-level = <8>; -+ }; -+ -+ panel { -+ compatible = "innolux,n125hce-gn1", "simple-panel"; -+ power-supply = <®_vref_3v3>; -+ backlight = <&backlight>; -+ no-hpd; -+ -+ port { -+ panel_in: endpoint { -+ remote-endpoint = <&edp_bridge_out>; -+ }; -+ }; - }; - - sound { -@@ -99,17 +129,206 @@ - "RINPUT2", "Line In Jack"; - model = "wm8960-audio"; - }; -+ -+ pcie1_refclk: pcie1-refclk { -+ compatible = "fixed-clock"; -+ #clock-cells = <0>; -+ clock-frequency = <100000000>; -+ }; -+}; -+ -+&A53_0 { -+ cpu-supply = <®_arm_dram>; -+}; -+ -+&A53_1 { -+ cpu-supply = <®_arm_dram>; -+}; -+ -+&A53_2 { -+ cpu-supply = <®_arm_dram>; -+}; -+ -+&A53_3 { -+ cpu-supply = <®_arm_dram>; -+}; -+ -+/ { -+ soc@0 { -+ bus@32c00000 { -+ dcss: display-controller@32e00000 { -+ status = "okay"; -+ -+ compatible = "nxp,imx8mq-dcss"; -+ reg = <0x32e00000 0x2d000>, <0x32e2f000 0x1000>; -+ interrupts = <6>, <8>, <9>; -+ interrupt-names = "ctxld", "ctxld_kick", "vblank"; -+ interrupt-parent = <&irqsteer>; -+ clocks = <&clk IMX8MQ_CLK_DISP_APB_ROOT>, -+ <&clk IMX8MQ_CLK_DISP_AXI_ROOT>, -+ <&clk IMX8MQ_CLK_DISP_RTRM_ROOT>, -+ <&clk IMX8MQ_CLK_DC_PIXEL>, -+ <&clk IMX8MQ_CLK_DISP_DTRC>, -+ <&clk IMX8MQ_VIDEO2_PLL1_REF_SEL>, -+ <&hdmi_phy_27m>; -+ clock-names = "apb", "axi", "rtrm", "pix", "dtrc", "pll_src", "pll_phy_ref"; -+ assigned-clocks = <&clk IMX8MQ_CLK_DISP_AXI>, -+ <&clk IMX8MQ_CLK_DISP_RTRM>, -+ <&clk IMX8MQ_VIDEO2_PLL1_REF_SEL>, -+ <&clk IMX8MQ_VIDEO_PLL1_REF_SEL>, -+ <&clk IMX8MQ_CLK_DC_PIXEL>; -+ assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_800M>, -+ <&clk IMX8MQ_SYS1_PLL_800M>, -+ <&clk IMX8MQ_CLK_27M>, -+ <&clk IMX8MQ_CLK_25M>, -+ <&clk IMX8MQ_VIDEO_PLL1_OUT>; -+ assigned-clock-rates = <800000000>, -+ <400000000>, -+ <27000000>, -+ <25000000>, -+ <594000000>; -+ -+ // internal display (MIPI-DSI/eDP) -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ port@0 { -+ reg = <0>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ dcss_dsi_out: endpoint@0 { -+ reg = <0>; -+ remote-endpoint = <&mipi_dsi_in>; -+ }; -+ }; -+ }; -+ }; -+ }; -+ }; -+}; -+ -+// LCDIF is not used, but has to be active or DCSS won't work -+&lcdif { -+ status = "okay"; -+ /delete-node/ port; - }; - - &dphy { -+ status = "okay"; - assigned-clocks = <&clk IMX8MQ_CLK_DSI_PHY_REF>; - assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_800M>; - assigned-clock-rates = <25000000>; -- status = "okay"; - }; - - &fec1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_fec1>; -+ phy-mode = "rgmii-id"; -+ phy-handle = <ðphy0>; -+ fsl,magic-packet; -+ status = "okay"; -+ -+ mdio { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ ethphy0: ethernet-phy@4 { -+ compatible = "ethernet-phy-ieee802.3-c22"; -+ reg = <4>; -+ interrupts = <&gpio1 11 IRQ_TYPE_LEVEL_LOW>; -+ reset-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; -+ reset-assert-us = <10000>; -+ reset-deassert-us = <300>; -+ }; -+ }; -+}; -+ -+&i2c1 { -+ clock-frequency = <400000>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_i2c1>; - status = "okay"; -+ -+ // I2C Mux on Nitrogen8M_SOM -+ i2cmux@70 { -+ compatible = "nxp,pca9546"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_i2c1_pca9546>; -+ reg = <0x70>; -+ reset-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ i2c1a: i2c1@0 { -+ reg = <0>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ // Regulator on Nitrogen8M_SOM -+ reg_arm_dram: fan53555@60 { -+ compatible = "fcs,fan53555"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_reg_arm_dram>; -+ reg = <0x60>; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <1000000>; -+ regulator-ramp-delay = <8000>; -+ regulator-always-on; -+ vsel-gpios = <&gpio3 24 GPIO_ACTIVE_HIGH>; -+ }; -+ }; -+ -+ i2c1b: i2c1@1 { -+ reg = <1>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ // Regulator on Nitrogen8M_SOM -+ reg_dram_1p1v: fan53555@60 { -+ compatible = "fcs,fan53555"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_reg_dram_1p1v>; -+ reg = <0x60>; -+ regulator-min-microvolt = <1100000>; -+ regulator-max-microvolt = <1100000>; -+ regulator-ramp-delay = <8000>; -+ regulator-always-on; -+ vsel-gpios = <&gpio2 11 GPIO_ACTIVE_HIGH>; -+ }; -+ }; -+ -+ i2c1c: i2c1@2 { -+ reg = <2>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ // Regulator on Nitrogen8M_SOM -+ reg_soc_gpu_vpu: fan53555@60 { -+ compatible = "fcs,fan53555"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_reg_soc_gpu_vpu>; -+ reg = <0x60>; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <1000000>; -+ regulator-ramp-delay = <8000>; -+ regulator-always-on; -+ vsel-gpios = <&gpio2 20 GPIO_ACTIVE_HIGH>; -+ }; -+ }; -+ -+ // No peripheral connected, available on DSI connector -+ i2c1d: i2c1@3 { -+ reg = <3>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ }; -+}; -+ -+// No peripheral connected, available on CSI connector -+&i2c2 { -+ status = "disabled"; - }; - - &i2c3 { -@@ -117,6 +336,7 @@ - pinctrl-0 = <&pinctrl_i2c3>; - status = "okay"; - -+ // Audio chip on motherboard - wm8960: codec@1a { - compatible = "wlf,wm8960"; - reg = <0x1a>; -@@ -125,7 +345,8 @@ - #sound-dai-cells = <0>; - }; - -- rtc@68 { -+ // Realtime clock chip on motherboard -+ pcf8523: pcf8523@68 { - compatible = "nxp,pcf8523"; - reg = <0x68>; - }; -@@ -134,13 +355,11 @@ - &i2c4 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_i2c4>; -- clock-frequency = <400000>; - status = "okay"; - -- edp_bridge: bridge@2c { -+ // DSI to eDP converter on motherboard -+ edp_bridge: sn65dsi86@2c { - compatible = "ti,sn65dsi86"; -- pinctrl-names = "default"; -- pinctrl-0 = <&pinctrl_edp_bridge>; - reg = <0x2c>; - enable-gpios = <&gpio3 20 GPIO_ACTIVE_HIGH>; - vccio-supply = <®_main_1v8>; -@@ -171,20 +390,277 @@ - }; - }; - --&lcdif { -- assigned-clocks = <&clk IMX8MQ_CLK_LCDIF_PIXEL>; -- assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_800M>; -- /delete-property/assigned-clock-rates; -- status = "okay"; -+// TODO: add external pin numbers -+&iomuxc { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_hog>; -+ -+ pinctrl_hog: hoggrp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_SAI5_RXC_GPIO3_IO20 0x19 // WL_EN on Nitrogen8M_SOM, pin 38, goes to /EN input of SN65DSI86 -+ MX8MQ_IOMUXC_GPIO1_IO14_GPIO1_IO14 0x56 // TODO: check pullup of usb hub reset on the board (0x40) -+ >; -+ }; -+ -+ pinctrl_fec1: fec1grp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_ENET_MDC_ENET1_MDC 0x3 -+ MX8MQ_IOMUXC_ENET_MDIO_ENET1_MDIO 0x23 -+ MX8MQ_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x1f -+ MX8MQ_IOMUXC_ENET_TXC_ENET1_RGMII_TXC 0x1f -+ MX8MQ_IOMUXC_ENET_TD0_ENET1_RGMII_TD0 0x1f -+ MX8MQ_IOMUXC_ENET_TD1_ENET1_RGMII_TD1 0x1f -+ MX8MQ_IOMUXC_ENET_TD2_ENET1_RGMII_TD2 0x1f -+ MX8MQ_IOMUXC_ENET_TD3_ENET1_RGMII_TD3 0x1f -+ MX8MQ_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91 -+ MX8MQ_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0xd1 -+ MX8MQ_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 0x91 -+ MX8MQ_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 0x91 -+ MX8MQ_IOMUXC_ENET_RD2_ENET1_RGMII_RD2 0x91 -+ MX8MQ_IOMUXC_ENET_RD3_ENET1_RGMII_RD3 0xd1 -+ MX8MQ_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x1 -+ MX8MQ_IOMUXC_GPIO1_IO11_GPIO1_IO11 0x41 -+ >; -+ }; -+ -+ pinctrl_i2c1: i2c1grp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_I2C1_SCL_I2C1_SCL 0x40000022 -+ MX8MQ_IOMUXC_I2C1_SDA_I2C1_SDA 0x40000022 -+ >; -+ }; -+ -+ pinctrl_i2c1_pca9546: i2c1-pca9546grp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_GPIO1_IO04_GPIO1_IO4 0x46 -+ >; -+ }; -+ -+ pinctrl_i2c2: i2c2grp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_I2C2_SCL_I2C2_SCL 0x40000022 -+ MX8MQ_IOMUXC_I2C2_SDA_I2C2_SDA 0x40000022 -+ >; -+ }; -+ -+ pinctrl_i2c3: i2c3grp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_I2C3_SCL_I2C3_SCL 0x40000022 -+ MX8MQ_IOMUXC_I2C3_SDA_I2C3_SDA 0x40000022 -+ >; -+ }; -+ -+ pinctrl_i2c4: i2c4grp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_I2C4_SCL_I2C4_SCL 0x40000022 -+ MX8MQ_IOMUXC_I2C4_SDA_I2C4_SDA 0x40000022 -+ >; -+ }; -+ -+ pinctrl_pcie0: pcie0grp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_ECSPI1_MOSI_GPIO5_IO7 0x16 -+ >; -+ }; -+ -+ pinctrl_pcie1: pcie1grp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_SAI5_RXD2_GPIO3_IO23 0x16 -+ >; -+ }; -+ -+ pinctrl_pwm2: pwm2grp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_SPDIF_RX_PWM2_OUT 0x16 -+ >; -+ }; -+ -+ pinctrl_pwm3: pwm3grp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_SPDIF_TX_PWM3_OUT 0x16 -+ >; -+ }; -+ -+ // Backlight -+ pinctrl_pwm4: pwm4grp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_SAI3_MCLK_PWM4_OUT 0x16 -+ >; -+ }; -+ -+ pinctrl_reg_arm_dram: reg-arm-dram { -+ fsl,pins = < -+ MX8MQ_IOMUXC_SAI5_RXD3_GPIO3_IO24 0x16 -+ >; -+ }; -+ -+ pinctrl_reg_dram_1p1v: reg-dram-1p1v { -+ fsl,pins = < -+ MX8MQ_IOMUXC_SD1_STROBE_GPIO2_IO11 0x16 -+ >; -+ }; -+ -+ pinctrl_reg_soc_gpu_vpu: reg-soc-gpu-vpu { -+ fsl,pins = < -+ MX8MQ_IOMUXC_SD2_WP_GPIO2_IO20 0x16 -+ >; -+ }; -+ -+ pinctrl_sai2: sai2grp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_SAI2_RXD0_SAI2_RX_DATA0 0xd6 /* Pin 166 */ -+ MX8MQ_IOMUXC_SAI2_RXFS_SAI2_RX_SYNC 0xd6 /* Pin 168 */ -+ MX8MQ_IOMUXC_SAI2_TXC_SAI2_TX_BCLK 0xd6 /* Pin 170 */ -+ MX8MQ_IOMUXC_SAI2_TXFS_SAI2_TX_SYNC 0xd6 /* Pin 172 */ -+ MX8MQ_IOMUXC_SAI2_RXC_SAI2_RX_BCLK 0xd6 /* Pin 174 */ -+ MX8MQ_IOMUXC_SAI2_MCLK_SAI2_MCLK 0xd6 /* Pin 176 */ -+ MX8MQ_IOMUXC_SAI2_TXD0_SAI2_TX_DATA0 0xd6 /* Pin 168 */ -+ >; -+ }; -+ -+ pinctrl_uart1: uart1grp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_UART1_RXD_UART1_DCE_RX 0x45 -+ MX8MQ_IOMUXC_UART1_TXD_UART1_DCE_TX 0x45 -+ >; -+ }; -+ -+ pinctrl_uart2: uart2grp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_UART2_RXD_UART2_DCE_RX 0x45 -+ MX8MQ_IOMUXC_UART2_TXD_UART2_DCE_TX 0x45 -+ >; -+ }; -+ -+ pinctrl_uart3: uart3grp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_UART3_RXD_UART3_DCE_RX 0x45 -+ MX8MQ_IOMUXC_UART3_TXD_UART3_DCE_TX 0x45 -+ >; -+ }; -+ -+ pinctrl_usdhc1: usdhc1grp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x83 -+ MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xc3 -+ MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xc3 -+ MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xc3 -+ MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xc3 -+ MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xc3 -+ MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xc3 -+ MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xc3 -+ MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xc3 -+ MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xc3 -+ MX8MQ_IOMUXC_SD1_RESET_B_GPIO2_IO10 0x41 -+ >; -+ }; -+ -+ pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x8d -+ MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xcd -+ MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xcd -+ MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xcd -+ MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xcd -+ MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xcd -+ MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xcd -+ MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xcd -+ MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xcd -+ MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xcd -+ >; -+ }; -+ -+ pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x9f -+ MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xdf -+ MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xdf -+ MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xdf -+ MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xdf -+ MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xdf -+ MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xdf -+ MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xdf -+ MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xdf -+ MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xdf -+ >; -+ }; -+ -+ pinctrl_usdhc2: usdhc2grp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x03 -+ MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xc3 -+ MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xc3 -+ MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xc3 -+ MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xc3 -+ MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xc -+ >; -+ }; -+ -+ pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x0d -+ MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xcd -+ MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xcd -+ MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xcd -+ MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xcd -+ MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xcd -+ >; -+ }; -+ -+ pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x1e -+ MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xce -+ MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xce -+ MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xce -+ MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xce -+ MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xce -+ >; -+ }; -+ -+ pinctrl_wdog: wdoggrp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0xc6 -+ >; -+ }; -+ -+ pinctrl_ecspi2: ecspi2grp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI 0x19 -+ MX8MQ_IOMUXC_ECSPI2_MISO_ECSPI2_MISO 0x19 -+ MX8MQ_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK 0x19 -+ >; -+ }; -+ -+ pinctrl_ecspi2_cs: ecspi2csgrp { -+ fsl,pins = < -+ MX8MQ_IOMUXC_ECSPI2_SS0_GPIO5_IO13 0x19 -+ >; -+ }; - }; - - &mipi_dsi { - status = "okay"; - - ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ port@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ -+ // We don't want input from LCDIF -+ /delete-node/ endpoint@0; -+ -+ mipi_dsi_in: endpoint@1 { -+ reg = <1>; -+ remote-endpoint = <&dcss_dsi_out>; -+ }; -+ }; - port@1 { - reg = <1>; -- - mipi_dsi_out: endpoint { - remote-endpoint = <&edp_bridge_in>; - }; -@@ -192,14 +668,41 @@ - }; - }; - -+&pcie0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_pcie0>; -+ reset-gpio = <&gpio5 7 GPIO_ACTIVE_LOW>; -+ internal-refclk; -+ -+ clocks = <&clk IMX8MQ_CLK_PCIE1_ROOT>, -+ <&clk IMX8MQ_CLK_PCIE1_AUX>, -+ <&clk IMX8MQ_CLK_PCIE1_PHY>, -+ <&clk IMX8MQ_CLK_MON_CLK2_OUT>; -+ -+ clock-names = "pcie", "pcie_aux", "pcie_phy", "pcie_bus"; -+ -+ assigned-clocks = <&clk IMX8MQ_CLK_PCIE1_CTRL>, -+ <&clk IMX8MQ_CLK_PCIE1_PHY>, -+ <&clk IMX8MQ_CLK_MON_CLK2_OUT>; -+ assigned-clock-rates = <250000000>, -+ <100000000>, -+ <100000000>; -+ assigned-clock-parents = <&clk IMX8MQ_SYS2_PLL_250M>, -+ <&clk IMX8MQ_SYS2_PLL_100M>; -+ -+ status = "okay"; -+}; -+ - &pcie1 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_pcie1>; - reset-gpio = <&gpio3 23 GPIO_ACTIVE_LOW>; -+ - clocks = <&clk IMX8MQ_CLK_PCIE2_ROOT>, -- <&pcie1_refclk>, -- <&clk IMX8MQ_CLK_PCIE2_PHY>, -- <&clk IMX8MQ_CLK_PCIE2_AUX>; -+ <&clk IMX8MQ_CLK_PCIE2_AUX>, -+ <&clk IMX8MQ_CLK_PCIE2_PHY>, -+ <&pcie1_refclk>; -+ clock-names = "pcie", "pcie_aux", "pcie_phy", "pcie_bus"; - status = "okay"; - }; - -@@ -209,24 +712,17 @@ - status = "okay"; - }; - --®_1p8v { -- vin-supply = <®_main_5v>; --}; -- --®_snvs { -- vin-supply = <®_main_5v>; --}; -- --®_arm_dram { -- vin-supply = <®_main_5v>; --}; -- --®_dram_1p1v { -- vin-supply = <®_main_5v>; -+&pwm3 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_pwm3>; -+ status = "okay"; - }; - --®_soc_gpu_vpu { -- vin-supply = <®_main_5v>; -+// Backlight control -+&pwm4 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_pwm4>; -+ status = "okay"; - }; - - &sai2 { -@@ -235,119 +731,106 @@ - assigned-clocks = <&clk IMX8MQ_CLK_SAI2>; - assigned-clock-parents = <&clk IMX8MQ_CLK_25M>; - assigned-clock-rates = <25000000>; -- fsl,sai-mclk-direction-output; -- fsl,sai-asynchronous; - status = "okay"; - }; - -+// Don't use i.MX8M internal RTC because we have a dedicated one - &snvs_rtc { - status = "disabled"; - }; - --&uart2 { -+// Console -+&uart1 { - pinctrl-names = "default"; -- pinctrl-0 = <&pinctrl_uart2>; -+ pinctrl-0 = <&pinctrl_uart1>; - status = "okay"; - }; - --&usb3_phy0 { -- vbus-supply = <®_main_usb>; -+// Auxiliary serial port on motherboard -+&uart2 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_uart2>; - status = "okay"; - }; - --&usb3_phy1 { -- vbus-supply = <®_main_usb>; -+// connected to LPC11U24 chip on the motherboard -+&uart3 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_uart3>; - status = "okay"; - }; - - &usb_dwc3_0 { -- dr_mode = "host"; - status = "okay"; -+ dr_mode = "host"; - }; - - &usb_dwc3_1 { -+ status = "okay"; - dr_mode = "host"; -+}; -+ -+&usb3_phy0 { -+ vbus-supply = <®_vref_5v>; -+ status = "okay"; -+}; -+ -+&usb3_phy1 { -+ vbus-supply = <®_vref_5v>; -+ status = "okay"; -+}; -+ -+// eMMC on Nitrogen8M_SOM -+// TODO: HS currently doesn't work -+&usdhc1 { -+ bus-width = <8>; -+ fsl,strobe-dll-delay-target = <5>; -+ fsl,tuning-start-tap = <63>; -+ fsl,tuning-step = <2>; -+ non-removable; -+ no-sd; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_usdhc1>; -+ vmmc-supply = <®_vref_1v8>; -+ vqmmc-1-8-v; - status = "okay"; - }; - -+// SD Card on motherboard -+// TODO: check keep-power-in-suspend, cap-sdio-irq - &usdhc2 { - assigned-clocks = <&clk IMX8MQ_CLK_USDHC2>; - assigned-clock-rates = <200000000>; -- pinctrl-names = "default"; -- pinctrl-0 = <&pinctrl_usdhc2>; -- vqmmc-supply = <®_main_3v3>; -- vmmc-supply = <®_main_3v3>; - bus-width = <4>; -+ pinctrl-names = "default", "state_100mhz", "state_200mhz"; -+ pinctrl-0 = <&pinctrl_usdhc2>; -+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>; -+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>; -+ vmmc-supply = <®_vref_3v3>; -+ vqmmc-supply = <®_vref_3v3>; -+ cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>; - status = "okay"; - }; - --&iomuxc { -- pinctrl_backlight: backlightgrp { -- fsl,pins = < -- MX8MQ_IOMUXC_GPIO1_IO10_GPIO1_IO10 0x3 -- >; -- }; -- -- pinctrl_edp_bridge: edpbridgegrp { -- fsl,pins = < -- MX8MQ_IOMUXC_SAI5_RXC_GPIO3_IO20 0x1 -- >; -- }; -- -- pinctrl_i2c3: i2c3grp { -- fsl,pins = < -- MX8MQ_IOMUXC_I2C3_SCL_I2C3_SCL 0x40000022 -- MX8MQ_IOMUXC_I2C3_SDA_I2C3_SDA 0x40000022 -- >; -- }; -- -- pinctrl_i2c4: i2c4grp { -- fsl,pins = < -- MX8MQ_IOMUXC_I2C4_SCL_I2C4_SCL 0x40000022 -- MX8MQ_IOMUXC_I2C4_SDA_I2C4_SDA 0x40000022 -- >; -- }; -- -- pinctrl_pcie1: pcie1grp { -- fsl,pins = < -- MX8MQ_IOMUXC_SAI5_RXD2_GPIO3_IO23 0x16 -- >; -- }; -- -- pinctrl_pwm2: pwm2grp { -- fsl,pins = < -- MX8MQ_IOMUXC_SPDIF_RX_PWM2_OUT 0x3 -- >; -- }; -- -- pinctrl_sai2: sai2grp { -- fsl,pins = < -- MX8MQ_IOMUXC_SAI2_RXD0_SAI2_RX_DATA0 0xd6 -- MX8MQ_IOMUXC_SAI2_RXFS_SAI2_RX_SYNC 0xd6 -- MX8MQ_IOMUXC_SAI2_TXC_SAI2_TX_BCLK 0xd6 -- MX8MQ_IOMUXC_SAI2_TXFS_SAI2_TX_SYNC 0xd6 -- MX8MQ_IOMUXC_SAI2_RXC_SAI2_RX_BCLK 0xd6 -- MX8MQ_IOMUXC_SAI2_MCLK_SAI2_MCLK 0xd6 -- MX8MQ_IOMUXC_SAI2_TXD0_SAI2_TX_DATA0 0xd6 -- >; -- }; -+&wdog1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_wdog>; -+ fsl,ext-reset-output; // TODO check source for what this means -+ status = "okay"; -+}; - -- pinctrl_uart2: uart2grp { -- fsl,pins = < -- MX8MQ_IOMUXC_UART2_RXD_UART2_DCE_RX 0x45 -- MX8MQ_IOMUXC_UART2_TXD_UART2_DCE_TX 0x45 -- >; -- }; -+&ecspi2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_ecspi2 &pinctrl_ecspi2_cs>; -+ cs-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>; -+ status = "okay"; -+ fsl,spi-num-chipselects = <1>; - -- pinctrl_usdhc2: usdhc2grp { -- fsl,pins = < -- MX8MQ_IOMUXC_SD2_CD_B_USDHC2_CD_B 0x0 -- MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x83 -- MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xc3 -- MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xc3 -- MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xc3 -- MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xc3 -- MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xc3 -- >; -+ spidev@0 { -+ compatible = "mntre,lpc11u24"; -+ spi-max-frequency = <1000000>; -+ reg = <0>; - }; - }; diff --git a/gnu/packages/patches/reform/imx8mp-mnt-pocket-reform/2ghz/0001-imx8mp-2ghz-clk.patch b/gnu/packages/patches/reform/imx8mp-mnt-pocket-reform/2ghz/0001-imx8mp-2ghz-clk.patch deleted file mode 100644 index 6bf30fff71..0000000000 --- a/gnu/packages/patches/reform/imx8mp-mnt-pocket-reform/2ghz/0001-imx8mp-2ghz-clk.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 02e8c29cac92595796138bf756006635e404b507 Mon Sep 17 00:00:00 2001 -From: "Lukas F. Hartmann" <lukas@mntre.com> -Date: Sun, 9 Jul 2023 22:19:22 +0200 -Subject: [PATCH 1/2] imx8mp-2ghz-clk - ---- - drivers/clk/imx/clk-pll14xx.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - ---- a/drivers/clk/imx/clk-pll14xx.c -+++ b/drivers/clk/imx/clk-pll14xx.c -@@ -45,6 +45,8 @@ struct clk_pll14xx { - #define to_clk_pll14xx(_hw) container_of(_hw, struct clk_pll14xx, hw) - - static const struct imx_pll14xx_rate_table imx_pll1416x_tbl[] = { -+ PLL_1416X_RATE(2400000000U, 300, 3, 0), -+ PLL_1416X_RATE(2000000000U, 250, 3, 0), - PLL_1416X_RATE(1800000000U, 225, 3, 0), - PLL_1416X_RATE(1600000000U, 200, 3, 0), - PLL_1416X_RATE(1500000000U, 375, 3, 1), -@@ -253,7 +255,7 @@ static unsigned long clk_pll14xx_recalc_ - - if (pll->type == PLL_1443X) { - pll_div_ctl1 = readl_relaxed(pll->base + DIV_CTL1); -- kdiv = (s16)FIELD_GET(KDIV_MASK, pll_div_ctl1); -+ kdiv = FIELD_GET(KDIV_MASK, pll_div_ctl1); - } else { - kdiv = 0; - } diff --git a/gnu/packages/patches/reform/imx8mp-mnt-pocket-reform/2ghz/0002-imx8mp-2ghz-opp.patch b/gnu/packages/patches/reform/imx8mp-mnt-pocket-reform/2ghz/0002-imx8mp-2ghz-opp.patch deleted file mode 100644 index 5a6ad865d2..0000000000 --- a/gnu/packages/patches/reform/imx8mp-mnt-pocket-reform/2ghz/0002-imx8mp-2ghz-opp.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 33e011e724aa70cb19c8c1fd6aa69a1addebe6de Mon Sep 17 00:00:00 2001 -From: "Lukas F. Hartmann" <lukas@mntre.com> -Date: Sun, 9 Jul 2023 22:19:23 +0200 -Subject: [PATCH 2/2] imx8mp-2ghz-opp - ---- - arch/arm64/boot/dts/freescale/imx8mp.dtsi | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi -index 3dc2102cbb3d..d55db50df4a3 100644 ---- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi -+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi -@@ -158,6 +158,14 @@ opp-1800000000 { - clock-latency-ns = <150000>; - opp-suspend; - }; -+ -+ opp-2000000000 { -+ opp-hz = /bits/ 64 <2000000000>; -+ opp-microvolt = <1000000>; -+ opp-supported-hw = <0x20>, <0x3>; -+ clock-latency-ns = <150000>; -+ opp-suspend; -+ }; - }; - - osc_32k: clock-osc-32k { --- -2.40.0 - diff --git a/gnu/packages/patches/reform/imx8mp-mnt-pocket-reform/audio/0000-revert-crashy-audiomix-pm-support.patch b/gnu/packages/patches/reform/imx8mp-mnt-pocket-reform/audio/0000-revert-crashy-audiomix-pm-support.patch deleted file mode 100644 index a45013be05..0000000000 --- a/gnu/packages/patches/reform/imx8mp-mnt-pocket-reform/audio/0000-revert-crashy-audiomix-pm-support.patch +++ /dev/null @@ -1,75 +0,0 @@ -diff --git a/drivers/clk/imx/clk-imx8mp-audiomix.c b/drivers/clk/imx/clk-imx8mp-audiomix.c -index b2cb157703c5..73e4fe9c5ff1 100644 ---- a/drivers/clk/imx/clk-imx8mp-audiomix.c -+++ b/drivers/clk/imx/clk-imx8mp-audiomix.c -@@ -13,7 +13,6 @@ - #include <linux/module.h> - #include <linux/of.h> - #include <linux/platform_device.h> --#include <linux/pm_runtime.h> - #include <linux/slab.h> - - #include <dt-bindings/clock/imx8mp-clock.h> -@@ -325,15 +324,6 @@ static int clk_imx8mp_audiomix_probe(struct platform_device *pdev) - priv->base = base; - dev_set_drvdata(dev, priv); - -- /* -- * pm_runtime_enable needs to be called before clk register. -- * That is to make core->rpm_enabled to be true for clock -- * usage. -- */ -- pm_runtime_get_noresume(dev); -- pm_runtime_set_active(dev); -- pm_runtime_enable(dev); -- - for (i = 0; i < ARRAY_SIZE(sels); i++) { - if (sels[i].num_parents == 1) { - hw = devm_clk_hw_register_gate_parent_data(dev, -@@ -411,20 +401,12 @@ static int clk_imx8mp_audiomix_probe(struct platform_device *pdev) - if (ret) - goto err_clk_register; - -- pm_runtime_put_sync(dev); - return 0; - - err_clk_register: -- pm_runtime_put_sync(dev); -- pm_runtime_disable(dev); - return ret; - } - --static void clk_imx8mp_audiomix_remove(struct platform_device *pdev) --{ -- pm_runtime_disable(&pdev->dev); --} -- - static int clk_imx8mp_audiomix_runtime_suspend(struct device *dev) - { - clk_imx8mp_audiomix_save_restore(dev, true); -@@ -439,13 +421,6 @@ static int clk_imx8mp_audiomix_runtime_resume(struct device *dev) - return 0; - } - --static const struct dev_pm_ops clk_imx8mp_audiomix_pm_ops = { -- RUNTIME_PM_OPS(clk_imx8mp_audiomix_runtime_suspend, -- clk_imx8mp_audiomix_runtime_resume, NULL) -- SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, -- pm_runtime_force_resume) --}; -- - static const struct of_device_id clk_imx8mp_audiomix_of_match[] = { - { .compatible = "fsl,imx8mp-audio-blk-ctrl" }, - { /* sentinel */ } -@@ -454,11 +429,9 @@ MODULE_DEVICE_TABLE(of, clk_imx8mp_audiomix_of_match); - - static struct platform_driver clk_imx8mp_audiomix_driver = { - .probe = clk_imx8mp_audiomix_probe, -- .remove = clk_imx8mp_audiomix_remove, - .driver = { - .name = "imx8mp-audio-blk-ctrl", - .of_match_table = clk_imx8mp_audiomix_of_match, -- .pm = pm_ptr(&clk_imx8mp_audiomix_pm_ops), - }, - }; - diff --git a/gnu/packages/patches/reform/imx8mp-mnt-pocket-reform/mmc-sdio/0001-sdhci-add-no-sd-uhs-sdr104-devicetree-property.patch b/gnu/packages/patches/reform/imx8mp-mnt-pocket-reform/mmc-sdio/0001-sdhci-add-no-sd-uhs-sdr104-devicetree-property.patch deleted file mode 100644 index 8449472306..0000000000 --- a/gnu/packages/patches/reform/imx8mp-mnt-pocket-reform/mmc-sdio/0001-sdhci-add-no-sd-uhs-sdr104-devicetree-property.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 9f11ce621bccb07064ccc9c564fb0cb20612e1cd Mon Sep 17 00:00:00 2001 -From: Troy Kisky <troy.kisky@boundarydevices.com> -Date: Fri, 1 Dec 2017 18:32:51 -0700 -Subject: [PATCH 1/3] sdhci: add no-sd-uhs-sdr104 devicetree property - -Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com> ---- - drivers/mmc/host/sdhci.c | 18 +++++++++++++----- - 1 file changed, 13 insertions(+), 5 deletions(-) - ---- a/drivers/mmc/host/sdhci.c -+++ b/drivers/mmc/host/sdhci.c -@@ -16,6 +16,7 @@ - #include <linux/highmem.h> - #include <linux/io.h> - #include <linux/module.h> -+#include <linux/of.h> - #include <linux/dma-mapping.h> - #include <linux/slab.h> - #include <linux/scatterlist.h> -@@ -4550,12 +4551,19 @@ int sdhci_setup_host(struct sdhci_host * - - /* SDR104 supports also implies SDR50 support */ - if (host->caps1 & SDHCI_SUPPORT_SDR104) { -+ struct device_node *np; -+ - mmc->caps |= MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_SDR50; -- /* SD3.0: SDR104 is supported so (for eMMC) the caps2 -- * field can be promoted to support HS200. -- */ -- if (!(host->quirks2 & SDHCI_QUIRK2_BROKEN_HS200)) -- mmc->caps2 |= MMC_CAP2_HS200; -+ np = mmc->parent->of_node; -+ if (of_property_read_bool(np, "no-sd-uhs-sdr104")) { -+ mmc->caps &= ~MMC_CAP_UHS_SDR104; -+ } else { -+ /* SD3.0: SDR104 is supported so (for eMMC) the caps2 -+ * field can be promoted to support HS200. -+ */ -+ if (!(host->quirks2 & SDHCI_QUIRK2_BROKEN_HS200)) -+ mmc->caps2 |= MMC_CAP2_HS200; -+ } - } else if (host->caps1 & SDHCI_SUPPORT_SDR50) { - mmc->caps |= MMC_CAP_UHS_SDR50; - } diff --git a/gnu/packages/patches/reform/imx8mp-mnt-pocket-reform/mmc-sdio/0002-During-the-card-init-the-host-side-sometimes-may-nee.patch b/gnu/packages/patches/reform/imx8mp-mnt-pocket-reform/mmc-sdio/0002-During-the-card-init-the-host-side-sometimes-may-nee.patch deleted file mode 100644 index b451da129f..0000000000 --- a/gnu/packages/patches/reform/imx8mp-mnt-pocket-reform/mmc-sdio/0002-During-the-card-init-the-host-side-sometimes-may-nee.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 59e34fd41e32a11bd05494c44402ff202ef9e570 Mon Sep 17 00:00:00 2001 -From: Haibo Chen <haibo.chen@xxxxxxx> -Date: Sun, 9 Jul 2023 22:16:01 +0200 -Subject: [PATCH 2/3] During the card init, the host side sometimes may need to - distinguish the card type to handle accordingly. So need to give host->card - value earlier. - -Signed-off-by: Haibo Chen <haibo.chen@xxxxxxx> ---- - drivers/mmc/core/mmc.c | 9 +++++---- - drivers/mmc/core/sd.c | 7 +++++-- - drivers/mmc/core/sdio.c | 10 ++++++---- - 3 files changed, 16 insertions(+), 10 deletions(-) - ---- a/drivers/mmc/core/mmc.c -+++ b/drivers/mmc/core/mmc.c -@@ -1657,6 +1657,8 @@ static int mmc_init_card(struct mmc_host - goto err; - } - -+ host->card = card; -+ - card->ocr = ocr; - card->type = MMC_TYPE_MMC; - card->rca = 1; -@@ -1931,14 +1933,13 @@ static int mmc_init_card(struct mmc_host - goto free_card; - } - -- if (!oldcard) -- host->card = card; -- - return 0; - - free_card: -- if (!oldcard) -+ if (!oldcard) { - mmc_remove_card(card); -+ host->card = NULL; -+ } - err: - return err; - } ---- a/drivers/mmc/core/sd.c -+++ b/drivers/mmc/core/sd.c -@@ -1431,6 +1431,8 @@ retry: - if (IS_ERR(card)) - return PTR_ERR(card); - -+ host->card = card; -+ - card->ocr = ocr; - card->type = MMC_TYPE_SD; - memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); -@@ -1577,12 +1579,13 @@ cont: - goto free_card; - } - -- host->card = card; - return 0; - - free_card: -- if (!oldcard) -+ if (!oldcard) { - mmc_remove_card(card); -+ host->card = NULL; -+ } - - return err; - } ---- a/drivers/mmc/core/sdio.c -+++ b/drivers/mmc/core/sdio.c -@@ -699,6 +699,9 @@ try_again: - if (IS_ERR(card)) - return PTR_ERR(card); - -+ if (!oldcard) -+ host->card = card; -+ - if ((rocr & R4_MEMORY_PRESENT) && - mmc_sd_get_cid(host, ocr & rocr, card->raw_cid, NULL) == 0) { - card->type = MMC_TYPE_SD_COMBO; -@@ -800,8 +803,6 @@ try_again: - - if (oldcard) - mmc_remove_card(card); -- else -- host->card = card; - - return 0; - } -@@ -898,14 +899,15 @@ try_again: - goto remove; - } - -- host->card = card; - return 0; - - mismatch: - pr_debug("%s: Perhaps the card was replaced\n", mmc_hostname(host)); - remove: -- if (oldcard != card) -+ if (oldcard != card) { - mmc_remove_card(card); -+ host->card = NULL; -+ } - return err; - } - diff --git a/gnu/packages/patches/reform/imx8mp-mnt-pocket-reform/mmc-sdio/0003-USDHC-IP-has-one-limitation-the-tuning-circuit-can-t.patch b/gnu/packages/patches/reform/imx8mp-mnt-pocket-reform/mmc-sdio/0003-USDHC-IP-has-one-limitation-the-tuning-circuit-can-t.patch deleted file mode 100644 index 3b16d315ac..0000000000 --- a/gnu/packages/patches/reform/imx8mp-mnt-pocket-reform/mmc-sdio/0003-USDHC-IP-has-one-limitation-the-tuning-circuit-can-t.patch +++ /dev/null @@ -1,44 +0,0 @@ -From c39839e4da6c0a0f24ff2532a793b5829ce28e82 Mon Sep 17 00:00:00 2001 -From: Haibo Chen <haibo.chen@xxxxxxx> -Date: Sun, 9 Jul 2023 22:16:02 +0200 -Subject: [PATCH 3/3] USDHC IP has one limitation: the tuning circuit can't - handle the async sdio device interrupt correctly. When sdio device use 4 data - lines, async sdio interrupt will use the shared DAT[1], if enable auto tuning - circuit to check these 4 data lines, include the DAT[1], this circuit will - detect this interrupt, take this as data on DAT[1], and adjust the delay cell - wrongly, finally will cause the DATA/CMD CRC error. So for SDIO device, only - enable DAT[0] and CMD line for auto tuning. - -Signed-off-by: Haibo Chen <haibo.chen@xxxxxxx> ---- - drivers/mmc/host/sdhci-esdhc-imx.c | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - -diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c -index 03fe21a89021..de7030a09711 100644 ---- a/drivers/mmc/host/sdhci-esdhc-imx.c -+++ b/drivers/mmc/host/sdhci-esdhc-imx.c -@@ -475,6 +475,20 @@ static inline void usdhc_auto_tuning_mode_sel_and_en(struct sdhci_host *host) - if (imx_data->init_card_type == MMC_TYPE_SDIO) - auto_tune_buswidth = ESDHC_VEND_SPEC2_AUTO_TUNE_1BIT_EN; - -+ /* -+ * For USDHC, auto tuning circuit can not handle the async sdio -+ * device interrupt correctly. When sdio device use 4 data lines, -+ * async sdio interrupt will use the shared DAT[1], if enable auto -+ * tuning circuit check these 4 data lines, include the DAT[1], -+ * this circuit will detect this interrupt, take this as a data on -+ * DAT[1], and adjust the delay cell wrongly. -+ * This is the hardware design limitation, to avoid this, for sdio -+ * device, config the auto tuning circuit only check DAT[0] and CMD -+ * line. -+ */ -+ if (!host->mmc->card && mmc_card_sdio(host->mmc->card)) -+ auto_tune_buswidth = ESDHC_VEND_SPEC2_AUTO_TUNE_1BIT_EN; -+ - esdhc_clrset_le(host, ESDHC_VEND_SPEC2_AUTO_TUNE_MODE_MASK, - auto_tune_buswidth | ESDHC_VEND_SPEC2_AUTO_TUNE_CMD_EN, - ESDHC_VEND_SPEC2); --- -2.40.0 - diff --git a/gnu/packages/patches/reform/imx8mp-mnt-pocket-reform/pocket-panel/0001-v5-add-multi-display-panel-driver.patch b/gnu/packages/patches/reform/imx8mp-mnt-pocket-reform/pocket-panel/0001-v5-add-multi-display-panel-driver.patch deleted file mode 100644 index 6cf5334dc5..0000000000 --- a/gnu/packages/patches/reform/imx8mp-mnt-pocket-reform/pocket-panel/0001-v5-add-multi-display-panel-driver.patch +++ /dev/null @@ -1,900 +0,0 @@ -commit fc0096f4790838f878af23fcd837fee1ece6abe5 -Author: Lukas F. Hartmann <lukas@mntre.com> -Date: Tue Dec 17 13:20:47 2024 +0100 - - pocket: add v5 of auto-detecting multi display driver - -diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig -index 9f49b01..6a80933 100644 ---- a/drivers/gpu/drm/panel/Kconfig -+++ b/drivers/gpu/drm/panel/Kconfig -@@ -399,6 +399,17 @@ config DRM_PANEL_MANTIX_MLAF057WE51 - has a resolution of 720x1440 pixels, a built in backlight and touch - controller. - -+config DRM_PANEL_MNT_POCKET_REFORM -+ tristate "MNT Pocket Reform WUXGA DSI panel" -+ depends on OF -+ depends on DRM_MIPI_DSI -+ depends on BACKLIGHT_CLASS_DEVICE -+ help -+ Say Y here if you want to enable support for the DSI -+ panel as found in MNT Pocket Reform. -+ The panel has a 1200(RGB)×1920 (WUXGA) resolution and uses -+ 24 bit per pixel. -+ - config DRM_PANEL_NEC_NL8048HL11 - tristate "NEC NL8048HL11 RGB panel" - depends on GPIOLIB && OF && SPI -diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile -index 5581387..9058011 100644 ---- a/drivers/gpu/drm/panel/Makefile -+++ b/drivers/gpu/drm/panel/Makefile -@@ -39,6 +39,7 @@ obj-$(CONFIG_DRM_PANEL_LG_LB035Q02) += panel-lg-lb035q02.o - obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o - obj-$(CONFIG_DRM_PANEL_LG_SW43408) += panel-lg-sw43408.o - obj-$(CONFIG_DRM_PANEL_MAGNACHIP_D53E6EA8966) += panel-magnachip-d53e6ea8966.o -+obj-$(CONFIG_DRM_PANEL_MNT_POCKET_REFORM) += panel-mnt-pocket-reform.o - obj-$(CONFIG_DRM_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o - obj-$(CONFIG_DRM_PANEL_NEWVISION_NV3051D) += panel-newvision-nv3051d.o - obj-$(CONFIG_DRM_PANEL_NEWVISION_NV3052C) += panel-newvision-nv3052c.o -diff --git a/drivers/gpu/drm/panel/panel-mnt-pocket-reform.c b/drivers/gpu/drm/panel/panel-mnt-pocket-reform.c -new file mode 100644 -index 000000000000..3e945397bac5 ---- /dev/null -+++ b/drivers/gpu/drm/panel/panel-mnt-pocket-reform.c -@@ -0,0 +1,842 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (C) 2016 InforceComputing -+ * Author: Vinay Simha BN <simhavcs@gmail.com> -+ * -+ * Copyright (C) 2016 Linaro Ltd -+ * Author: Sumit Semwal <sumit.semwal@linaro.org> -+ * -+ * Copyright (C) 2024 MNT Research GmbH -+ * Author: Lukas Hartmann <lukas@mntre.com> -+ */ -+ -+#include <linux/backlight.h> -+#include <linux/delay.h> -+#include <linux/gpio/consumer.h> -+#include <linux/module.h> -+#include <linux/of.h> -+#include <linux/regulator/consumer.h> -+#include <linux/panel-mnt-pocket-reform.h> -+ -+#include <video/mipi_display.h> -+ -+#include <drm/drm_crtc.h> -+#include <drm/drm_mipi_dsi.h> -+#include <drm/drm_modes.h> -+#include <drm/drm_panel.h> -+ -+static const char * const regulator_names[] = { -+ "vddp", -+ "iovcc" -+}; -+ -+struct jdi_panel { -+ struct drm_panel base; -+ struct mipi_dsi_device *dsi; -+ -+ struct regulator_bulk_data supplies[ARRAY_SIZE(regulator_names)]; -+ -+ struct gpio_desc *enable_gpio; -+ struct gpio_desc *reset_gpio; -+ struct gpio_desc *dcdc_en_gpio; -+ struct backlight_device *backlight; -+ -+ bool prepared; -+ bool enabled; -+ -+ int panel_version; -+ int display_v1_init_count; -+ int display_v2_init_count; -+}; -+ -+static ssize_t panel_version_attr_show(struct device *dev, struct device_attribute *attr, char *buf) { -+ struct jdi_panel *jdi = (struct jdi_panel *)dev_get_drvdata(dev); -+ return sprintf(buf, "%d\n", jdi->panel_version); -+} -+static ssize_t panel_dcs_read_attr_show(struct device *dev, struct device_attribute *attr, char *buf) { -+ return sprintf(buf, "%d\n", 0); -+} -+static ssize_t panel_dcs_read_attr_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { -+ struct jdi_panel *jdi = (struct jdi_panel *)dev_get_drvdata(dev); -+ long command; -+ int ret = (int)kstrtol(buf, 10, &command); -+ u8 readval = 0; -+ if (ret == 0 && command > 0) { -+ jdi->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; -+ mipi_dsi_dcs_read(jdi->dsi, (int)command, &readval, sizeof(readval)); -+ dev_err(dev, "[mnt pocket reform display] DCS command %d read result: 0x%x\n", (int)command, (int)readval); -+ } -+ return count; -+} -+static DEVICE_ATTR(mnt_pocket_reform_panel_version, 0444, panel_version_attr_show, NULL); -+static DEVICE_ATTR(mnt_pocket_reform_panel_dcs_read, 0644, panel_dcs_read_attr_show, panel_dcs_read_attr_store); -+static struct attribute *mnt_pocket_reform_panel_attrs[] = { -+ &dev_attr_mnt_pocket_reform_panel_version.attr, -+ &dev_attr_mnt_pocket_reform_panel_dcs_read.attr, -+ NULL -+}; -+static const struct attribute_group mnt_pocket_reform_panel_attr_group = { -+ .attrs = mnt_pocket_reform_panel_attrs, -+}; -+ -+static int __global_mnt_pocket_reform_panel_version = 0; -+int mnt_pocket_reform_get_panel_version(void) -+{ -+ return __global_mnt_pocket_reform_panel_version; -+} -+EXPORT_SYMBOL_GPL(mnt_pocket_reform_get_panel_version); -+ -+static inline struct jdi_panel *to_jdi_panel(struct drm_panel *panel) -+{ -+ return container_of(panel, struct jdi_panel, base); -+} -+ -+static int dsi_dcs_bl_get_brightness(struct backlight_device *bl) -+{ -+ u16 brightness = bl->props.brightness; -+ return (int)brightness; -+} -+ -+static int dsi_dcs_bl_update_status(struct backlight_device *bl) -+{ -+ struct jdi_panel *jdi = bl_get_data(bl); -+ struct mipi_dsi_device *dsi = jdi->dsi; -+ -+ dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; -+ -+ mipi_dsi_dcs_set_display_brightness(dsi, bl->props.brightness); -+ -+ dsi->mode_flags |= MIPI_DSI_MODE_LPM; -+ -+ return 0; -+} -+ -+static const struct backlight_ops dsi_bl_ops = { -+ .update_status = dsi_dcs_bl_update_status, -+ .get_brightness = dsi_dcs_bl_get_brightness, -+}; -+ -+static struct backlight_device * -+drm_panel_create_dsi_backlight(struct jdi_panel *jdi) -+{ -+ struct device *dev = &jdi->dsi->dev; -+ struct backlight_properties props; -+ -+ memset(&props, 0, sizeof(props)); -+ props.type = BACKLIGHT_RAW; -+ props.brightness = 255; -+ props.max_brightness = 255; -+ -+ return devm_backlight_device_register(dev, dev_name(dev), dev, jdi, -+ &dsi_bl_ops, &props); -+} -+ -+static ssize_t dsi_write_raw(struct mipi_dsi_device *dsi, -+ const void *data, size_t len) -+{ -+ const struct mipi_dsi_msg msg = { -+ .channel = dsi->channel, -+ .tx_buf = data, -+ .tx_len = len, -+ .type = MIPI_DSI_DCS_LONG_WRITE, -+ .flags = MIPI_DSI_MSG_USE_LPM -+ }; -+ -+ return dsi->host->ops->transfer(dsi->host, &msg); -+} -+ -+static void pocket_display_v2_init(struct jdi_panel* jdi) { -+ struct mipi_dsi_device *dsi = jdi->dsi; -+ struct device *dev = &jdi->dsi->dev; -+ int ret; -+ -+ mipi_dsi_dcs_soft_reset(dsi); -+ msleep(20); -+ -+ // for unknown reasons, if we send all the data tables -+ // on the first init, it takes very long (~14 seconds), -+ // but it's quick the second time around. -+ if (jdi->display_v2_init_count > 0) { -+ dsi_write_raw(dsi, (u8[]) {0xE0,0xAB,0xBA}, 3); -+ dsi_write_raw(dsi, (u8[]) {0xFF,0x01}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x83,0x16}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x90,0x81}, 2); -+ -+ dsi_write_raw(dsi, (u8[]) {0xFF,0x02}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x80,0xA0}, 2); // vcom -+ dsi_write_raw(dsi, (u8[]) {0x81,0x50}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x82,0x50}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xA2,0xB0}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xA3,0x49}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xA4,0x6B}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xA5,0x34}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xA6,0x22}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xA7,0x34}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xA8,0x22}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xA9,0x51}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xAA,0xD4}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xAB,0xA6}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xAC,0x05}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xAD,0xAB}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xAE,0x3B}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xAF,0x1B}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xB0,0x1E}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xB1,0xAB}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xB2,0xC1}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xB3,0x22}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xB4,0xFF}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xB5,0xCC}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xB6,0x23}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xB7,0x01}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xBF,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xC0,0x0E}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xC1,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xC2,0xFF}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xC3,0x08}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xC5,0xFF}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xC7,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xC8,0x05}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xC9,0x12}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xCA,0x29}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xCB,0x41}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xCE,0x06}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xD1,0x7F}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xD2,0x6A}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xD3,0x63}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xD4,0x63}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xD5,0x61}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xD6,0x61}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xD7,0x5D}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xD8,0x5B}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xD9,0x55}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xDA,0x4D}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xDB,0x4B}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xDC,0x49}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xDD,0x47}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xDE,0x43}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xDF,0x27}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xE0,0x14}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xE1,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xE2,0x7F}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xE3,0x6A}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xE4,0x63}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xE5,0x63}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xE6,0x61}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xE7,0x61}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xE8,0x5D}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xE9,0x5B}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xEA,0x55}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xEB,0x4D}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xEC,0x4B}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xED,0x49}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xEE,0x47}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xEF,0x43}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xF0,0x27}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xF1,0x14}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xF2,0x00}, 2); -+ -+ dsi_write_raw(dsi, (u8[]) {0xFF,0x03}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x9D,0x00}, 2); -+ -+ dsi_write_raw(dsi, (u8[]) {0xFF,0x04}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x80,0xCD}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x81,0xCB}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x82,0xA9}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x83,0x8C}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x84,0x46}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x85,0x66}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x86,0x66}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x87,0x64}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x88,0xA0}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x89,0x08}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x8A,0xA0}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x8B,0x08}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x8C,0x02}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x8D,0x81}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x8E,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x8F,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x90,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x91,0x05}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x92,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x93,0x0F}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x94,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x95,0x08}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x96,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x97,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x98,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x99,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x9A,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x9B,0x01}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x9C,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x9D,0x74}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x9E,0x12}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x9F,0xB2}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xA0,0x07}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xA1,0xA0}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xA2,0x08}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xA3,0x60}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xA4,0x08}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xA5,0x02}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xA6,0x54}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xA7,0x80}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xA8,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xA9,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xAA,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xAB,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xAC,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xAD,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xAE,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xAF,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xB0,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xB1,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xB2,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xB3,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xB4,0x09}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xB5,0x01}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xB6,0x13}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xB7,0x08}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xB8,0x12}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xB9,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xBA,0x03}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xBB,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xBC,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xBD,0x01}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xBE,0x70}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xBF,0xBA}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xC0,0x98}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xC1,0x76}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xC2,0x54}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xC3,0x32}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xC4,0x10}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xC5,0xCD}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xC6,0xEF}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xC7,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xC8,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xC9,0x20}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xCB,0x21}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xCD,0x0B}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xCF,0x10}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xD0,0x12}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xD1,0x14}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xD2,0x16}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xD3,0x18}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xD4,0x1A}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xD5,0x05}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xD6,0x07}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xD7,0x09}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xD9,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xDA,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xDB,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xDC,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xDD,0x20}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xDF,0x21}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xE3,0x0B}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xE5,0x11}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xE6,0x13}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xE7,0x15}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xE8,0x17}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xE9,0x19}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xEA,0x1B}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xEB,0x06}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xEC,0x08}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xED,0x0A}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xEF,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xF0,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xF1,0xA2}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xF2,0x18}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xF3,0x11}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xF4,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xF5,0x11}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xF6,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xF7,0x11}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xF8,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xF9,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xFA,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xFB,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xFC,0x20}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xFD,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xFE,0x00}, 2); -+ -+ dsi_write_raw(dsi, (u8[]) {0xFF,0x05}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x8F,0xE8}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x90,0x84}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x91,0x77}, 2); -+ -+ dsi_write_raw(dsi, (u8[]) {0xFF,0x06}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x80,0x10}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x81,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x82,0x07}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x83,0x9F}, 2); -+ -+ dsi_write_raw(dsi, (u8[]) {0xFF,0x07}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x80,0x14}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x81,0x12}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x82,0x02}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x83,0x20}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x84,0x24}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x85,0x0C}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x86,0x39}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x87,0x77}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x88,0x80}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x89,0x33}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x8A,0x00}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x8B,0x04}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x8C,0x09}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x8D,0x40}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x8E,0x40}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x91,0x11}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x92,0x2C}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x93,0x2D}, 2); -+ dsi_write_raw(dsi, (u8[]) {0x94,0x03}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xA0,0x0A}, 2); -+ dsi_write_raw(dsi, (u8[]) {0xA2,0x13}, 2); -+ -+ dsi_write_raw(dsi, (u8[]) {0xFF,0x00}, 2); -+ dev_info(dev, "[display v2] sent tables OK\n"); -+ } else { -+ dev_info(dev, "[display v2] not sending tables this time\n"); -+ } -+ -+ jdi->display_v2_init_count++; -+ -+ ret = mipi_dsi_dcs_exit_sleep_mode(dsi); -+ if (ret < 0) { -+ dev_err(dev, "[display v2] failed to set exit sleep mode: %d\n", ret); -+ } -+ mdelay(100); -+ ret = mipi_dsi_dcs_set_display_on(dsi); -+ if (ret < 0) { -+ dev_err(dev, "[display v2] failed to set display on: %d\n", ret); -+ } -+ dev_info(dev, "[display v2] OK\n"); -+} -+ -+static void pocket_display_v1_init(struct jdi_panel* jdi) { -+ struct mipi_dsi_device *dsi = jdi->dsi; -+ struct device *dev = &jdi->dsi->dev; -+ int ret; -+ -+ ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY, (u8[]) {0x2c}, 1); -+ ret = mipi_dsi_dcs_set_pixel_format(dsi, MIPI_DCS_PIXEL_FMT_24BIT << 4); -+ if (ret < 0) { -+ dev_err(dev, "[display v1] failed to set pixel format: %d\n", ret); -+ } -+ -+ // write_memory_start -+ ret = mipi_dsi_generic_write(dsi, (u8[]) {0x2c}, 1); -+ ret = mipi_dsi_generic_write(dsi, (u8[]) {0x00}, 0); -+ -+ msleep(200); -+ ret = mipi_dsi_dcs_exit_sleep_mode(dsi); -+ if (ret < 0) { -+ dev_err(dev, "[display v1] failed to set exit sleep mode: %d\n", ret); -+ } -+ -+ // required delay -+ msleep(800); -+ -+ // MCAP off -+ ret = mipi_dsi_generic_write(dsi, (u8[]){0xB0, 0x00}, 2); -+ if (ret < 0) { -+ dev_err(dev, "[display v1] failed to set mcap: %d\n", ret); -+ } -+ -+ // required delay -+ mdelay(200); -+ -+ // Interface setting, video mode -+ ret = mipi_dsi_generic_write(dsi, (u8[]) -+ {0xB3, 0x14, 0x08, 0x00, 0x22, 0x00}, 6); -+ if (ret < 0) { -+ dev_err(dev, "[display v1] failed to set display interface setting: %d\n" -+ , ret); -+ } -+ -+ // interface ID setting -+ mdelay(20); -+ ret = mipi_dsi_generic_write(dsi, (u8[]) {0xb4, 0x0c}, 2); -+ -+ // DSI control -+ ret = mipi_dsi_generic_write(dsi, (u8[]) {0xb6, 0x3a, 0xd3}, 3); -+ ret = mipi_dsi_dcs_set_display_on(dsi); -+ -+ mipi_dsi_dcs_set_display_brightness(dsi, 127); -+} -+ -+static int jdi_panel_init(struct jdi_panel *jdi) -+{ -+ struct mipi_dsi_device *dsi = jdi->dsi; -+ struct device *dev = &jdi->dsi->dev; -+ int ret; -+ u8 readval = 0; -+ -+ if (of_property_present(dsi->dev.of_node, "probe-mode-lpm")) { -+ // imx8mplus, a311d -+ dsi->mode_flags |= MIPI_DSI_MODE_LPM; -+ } else { -+ // rk3588 -+ dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; -+ } -+ -+ msleep(20); -+ -+ if (!jdi->panel_version) { -+ mipi_dsi_dcs_read(dsi, 12, &readval, sizeof(readval)); -+ dev_err(dev, "[mnt pocket reform display] read register 12a: 0x%x\n", (int)readval); -+ -+ if (readval == 0x77 || readval == 0x70) { -+ jdi->panel_version = 1; -+ __global_mnt_pocket_reform_panel_version = 1; -+ } else { -+ jdi->panel_version = 2; -+ __global_mnt_pocket_reform_panel_version = 2; -+ } -+ } -+ -+ if (jdi->panel_version == 2) { -+ dsi->mode_flags |= MIPI_DSI_MODE_LPM; -+ // panel v2 doesn't like HSE -+ dsi->mode_flags &= ~MIPI_DSI_MODE_VIDEO_HSE; -+ dsi->mode_flags &= ~(MIPI_DSI_MODE_NO_EOT_PACKET | MIPI_DSI_MODE_VIDEO_NO_HFP | MIPI_DSI_MODE_VIDEO_NO_HBP | MIPI_DSI_MODE_VIDEO_NO_HSA); -+ -+ pocket_display_v2_init(jdi); -+ } else { -+ pocket_display_v1_init(jdi); -+ if (!jdi->backlight) { -+ jdi->backlight = drm_panel_create_dsi_backlight(jdi); -+ if (IS_ERR(jdi->backlight)) -+ return dev_err_probe(dev, PTR_ERR(jdi->backlight), -+ "failed to register backlight %d\n", ret); -+ backlight_enable(jdi->backlight); -+ } -+ } -+ -+ return 0; -+} -+ -+static int jdi_panel_disable(struct drm_panel *panel) -+{ -+ struct jdi_panel *jdi = to_jdi_panel(panel); -+ -+ if (!jdi->enabled) return 0; -+ -+ jdi->enabled = false; -+ mipi_dsi_dcs_set_display_off(jdi->dsi); -+ if (jdi->panel_version == 2) return 0; -+ -+ mipi_dsi_dcs_enter_sleep_mode(jdi->dsi); -+ msleep(100); -+ backlight_disable(jdi->backlight); -+ -+ return 0; -+} -+ -+static int jdi_panel_unprepare(struct drm_panel *panel) -+{ -+ struct jdi_panel *jdi = to_jdi_panel(panel); -+ struct device *dev = &jdi->dsi->dev; -+ int ret; -+ -+ if (!jdi->prepared) -+ return 0; -+ -+ ret = regulator_bulk_disable(ARRAY_SIZE(jdi->supplies), jdi->supplies); -+ if (ret < 0) -+ dev_err(dev, "regulator disable failed, %d\n", ret); -+ -+ if (!IS_ERR(jdi->enable_gpio)) gpiod_set_value(jdi->enable_gpio, 0); -+ -+ if (!IS_ERR(jdi->reset_gpio)) gpiod_set_value(jdi->reset_gpio, 1); -+ -+ if (!IS_ERR(jdi->dcdc_en_gpio)) gpiod_set_value(jdi->dcdc_en_gpio, 0); -+ -+ jdi->prepared = false; -+ -+ return 0; -+} -+ -+static int jdi_panel_prepare(struct drm_panel *panel) -+{ -+ struct jdi_panel *jdi = to_jdi_panel(panel); -+ struct device *dev = &jdi->dsi->dev; -+ int ret; -+ -+ if (!of_property_present(dev->of_node, "init-in-enable")) { -+ if (jdi->prepared) -+ return 0; -+ } -+ -+ ret = regulator_bulk_enable(ARRAY_SIZE(jdi->supplies), jdi->supplies); -+ if (ret < 0) { -+ dev_err(dev, "regulator enable failed, %d\n", ret); -+ return ret; -+ } -+ -+ msleep(20); -+ -+ if (!IS_ERR(jdi->dcdc_en_gpio)) gpiod_set_value(jdi->dcdc_en_gpio, 1); -+ usleep_range(10, 20); -+ -+ if (!IS_ERR(jdi->reset_gpio)) gpiod_set_value(jdi->reset_gpio, 0); -+ usleep_range(10, 20); -+ -+ if (!IS_ERR(jdi->enable_gpio)) gpiod_set_value(jdi->enable_gpio, 1); -+ usleep_range(10, 20); -+ -+ if (!of_property_present(dev->of_node, "init-in-enable")) { -+ // on a311d the panels only work -+ // if init is done in here, not in enable -+ dev_info(dev, "[display] init in prepare...\n"); -+ ret = jdi_panel_init(jdi); -+ if (ret < 0) { -+ dev_err(dev, "failed jdi_panel_init: %d\n", ret); -+ return ret; -+ } -+ } -+ -+ jdi->prepared = true; -+ -+ return 0; -+} -+ -+static int jdi_panel_enable(struct drm_panel *panel) -+{ -+ struct jdi_panel *jdi = to_jdi_panel(panel); -+ struct device *dev = &jdi->dsi->dev; -+ int ret; -+ -+ if (of_property_present(dev->of_node, "init-in-enable")) { -+ // on imx8mp the panels only work -+ // if init is done here, not in prepare -+ dev_info(dev, "[display] init in enable...\n"); -+ ret = jdi_panel_init(jdi); -+ if (ret < 0) { -+ dev_err(dev, "failed jdi_panel_init: %d\n", ret); -+ return ret; -+ } -+ } else { -+ jdi->dsi->mode_flags |= MIPI_DSI_MODE_LPM; -+ ret = mipi_dsi_dcs_set_display_on(jdi->dsi); -+ } -+ jdi->enabled = true; -+ -+ return 0; -+} -+ -+static const struct drm_display_mode panel_v1_mode = { -+ .clock = 140000, -+ .hdisplay = 1200, -+ .hsync_start = 1200 + 48, -+ .hsync_end = 1200 + 48 + 32, -+ .htotal = 1200 + 48 + 32 + 60, -+ .vdisplay = 1920, -+ .vsync_start = 1920 + 3, -+ .vsync_end = 1920 + 3 + 5, -+ .vtotal = 1920 + 3 + 5 + 6, -+ .flags = 0, -+}; -+ -+static const struct drm_display_mode panel_v2_mode = { -+ .clock = 140000, -+ .hdisplay = 1200, -+ .hsync_start = 1200 + 40, -+ .hsync_end = 1200 + 40 + 20, -+ .htotal = 1200 + 40 + 20 + 40, -+ .vdisplay = 1920, -+ .vsync_start = 1920 + 18, -+ .vsync_end = 1920 + 18 + 2, -+ .vtotal = 1920 + 18 + 2 + 20, -+ .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, -+}; -+ -+static int jdi_panel_get_modes(struct drm_panel *panel, -+ struct drm_connector *connector) -+{ -+ struct drm_display_mode *mode; -+ struct jdi_panel *jdi = to_jdi_panel(panel); -+ struct device *dev = &jdi->dsi->dev; -+ -+ if (jdi->panel_version == 2) { -+ mode = drm_mode_duplicate(connector->dev, &panel_v2_mode); -+ } else { -+ mode = drm_mode_duplicate(connector->dev, &panel_v1_mode); -+ -+ if (of_property_present(dev->of_node, "init-in-enable")) { -+ // a hack to force display pipeline reinit on -+ // imx8mp, otherwise the version probing read to dcs register 12 -+ // causes wrapping and color shift of display v1 -+ if (jdi->display_v1_init_count == 0) { -+ mode->clock = 145000; -+ jdi->display_v1_init_count++; -+ } -+ } -+ } -+ -+ if (!mode) { -+ dev_err(dev, "failed to add mode\n"); -+ return -ENOMEM; -+ } -+ -+ // on A311D, we shift the vsync by one line to counteract VIU_OSD_HOLD_FIFO_LINES -+ if (of_property_present(dev->of_node, "vsync-shift")) { -+ uint32_t vsync_shift = 0; -+ of_property_read_u32(dev->of_node, "vsync-shift", &vsync_shift); -+ dev_warn(dev, "vsync-shift from device tree: %d\n", vsync_shift); -+ mode->vsync_start += vsync_shift; -+ mode->vsync_end += vsync_shift; -+ } -+ -+ drm_mode_set_name(mode); -+ -+ drm_mode_probed_add(connector, mode); -+ -+ connector->display_info.width_mm = 95; -+ connector->display_info.height_mm = 151; -+ -+ return 1; -+} -+ -+static const struct drm_panel_funcs jdi_panel_funcs = { -+ .disable = jdi_panel_disable, -+ .unprepare = jdi_panel_unprepare, -+ .prepare = jdi_panel_prepare, -+ .enable = jdi_panel_enable, -+ .get_modes = jdi_panel_get_modes, -+}; -+ -+static const struct of_device_id jdi_of_match[] = { -+ { .compatible = "jdi,lt070me05000", }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, jdi_of_match); -+ -+static int jdi_panel_add(struct jdi_panel *jdi) -+{ -+ struct device *dev = &jdi->dsi->dev; -+ int ret; -+ unsigned int i; -+ -+ for (i = 0; i < ARRAY_SIZE(jdi->supplies); i++) -+ jdi->supplies[i].supply = regulator_names[i]; -+ -+ ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(jdi->supplies), -+ jdi->supplies); -+ if (ret < 0) -+ return dev_err_probe(dev, ret, -+ "failed to init regulator, ret=%d\n", ret); -+ -+ jdi->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW); -+ if (IS_ERR(jdi->enable_gpio)) -+ dev_err_probe(dev, PTR_ERR(jdi->enable_gpio), -+ "cannot get enable-gpio %d\n", ret); -+ -+ jdi->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); -+ if (IS_ERR(jdi->reset_gpio)) -+ dev_err_probe(dev, PTR_ERR(jdi->reset_gpio), -+ "cannot get reset-gpios %d\n", ret); -+ -+ jdi->dcdc_en_gpio = devm_gpiod_get(dev, "dcdc-en", GPIOD_OUT_LOW); -+ if (IS_ERR(jdi->dcdc_en_gpio)) -+ dev_err_probe(dev, PTR_ERR(jdi->dcdc_en_gpio), -+ "cannot get dcdc-en-gpio %d\n", ret); -+ -+ drm_panel_init(&jdi->base, &jdi->dsi->dev, &jdi_panel_funcs, -+ DRM_MODE_CONNECTOR_DSI); -+ -+ drm_panel_add(&jdi->base); -+ -+ return 0; -+} -+ -+static void jdi_panel_del(struct jdi_panel *jdi) -+{ -+ if (jdi->base.dev) -+ drm_panel_remove(&jdi->base); -+} -+ -+static int jdi_panel_probe(struct mipi_dsi_device *dsi) -+{ -+ struct jdi_panel *jdi; -+ int ret; -+ int err; -+ -+ dsi->lanes = 4; -+ dsi->format = MIPI_DSI_FMT_RGB888; -+ dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_HSE; -+ -+ // on a311d it works only without burst, but imx8mplus needs burst mode -+ if (of_property_present(dsi->dev.of_node, "burst-mode")) { -+ dsi->mode_flags |= MIPI_DSI_MODE_VIDEO_BURST; -+ dev_warn(&dsi->dev, "DSI burst mode enabled via device tree\n"); -+ } -+ if (of_property_present(dsi->dev.of_node, "no-eot-hfp-hbp-hsa")) { -+ dsi->mode_flags |= MIPI_DSI_MODE_NO_EOT_PACKET | MIPI_DSI_MODE_VIDEO_NO_HFP | MIPI_DSI_MODE_VIDEO_NO_HBP | MIPI_DSI_MODE_VIDEO_NO_HSA; -+ dev_warn(&dsi->dev, "DSI eot/hfp/hbp/hsa disabled via device tree\n"); -+ } -+ -+ jdi = devm_kzalloc(&dsi->dev, sizeof(*jdi), GFP_KERNEL); -+ if (!jdi) -+ return -ENOMEM; -+ -+ mipi_dsi_set_drvdata(dsi, jdi); -+ -+ jdi->dsi = dsi; -+ -+ ret = jdi_panel_add(jdi); -+ if (ret < 0) -+ return ret; -+ -+ ret = mipi_dsi_attach(dsi); -+ if (ret < 0) { -+ jdi_panel_del(jdi); -+ return ret; -+ } -+ -+ err = sysfs_create_group(&dsi->dev.kobj, &mnt_pocket_reform_panel_attr_group); -+ if (err) { -+ pr_err("failed to register pocket reform panel attr group\n"); -+ } -+ -+ return 0; -+} -+ -+static void jdi_panel_remove(struct mipi_dsi_device *dsi) -+{ -+ struct jdi_panel *jdi = mipi_dsi_get_drvdata(dsi); -+ int ret; -+ -+ ret = jdi_panel_disable(&jdi->base); -+ if (ret < 0) -+ dev_err(&dsi->dev, "failed to disable panel: %d\n", ret); -+ -+ ret = mipi_dsi_detach(dsi); -+ if (ret < 0) -+ dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", -+ ret); -+ -+ jdi_panel_del(jdi); -+} -+ -+static void jdi_panel_shutdown(struct mipi_dsi_device *dsi) -+{ -+ struct jdi_panel *jdi = mipi_dsi_get_drvdata(dsi); -+ -+ jdi_panel_disable(&jdi->base); -+} -+ -+static struct mipi_dsi_driver jdi_panel_driver = { -+ .driver = { -+ .name = "panel-mnt-pocket-reform", -+ .of_match_table = jdi_of_match, -+ }, -+ .probe = jdi_panel_probe, -+ .remove = jdi_panel_remove, -+ .shutdown = jdi_panel_shutdown, -+}; -+module_mipi_dsi_driver(jdi_panel_driver); -+ -+MODULE_AUTHOR("Sumit Semwal <sumit.semwal@linaro.org>"); -+MODULE_AUTHOR("Vinay Simha BN <simhavcs@gmail.com>"); -+MODULE_AUTHOR("Lukas Hartmann <lukas@mntre.com>"); -+MODULE_DESCRIPTION("MNT Pocket Reform Display WUXGA"); -+MODULE_LICENSE("GPL v2"); -diff --git a/include/linux/panel-mnt-pocket-reform.h b/include/linux/panel-mnt-pocket-reform.h -new file mode 100644 -index 000000000000..1a4d487d9d6c ---- /dev/null -+++ b/include/linux/panel-mnt-pocket-reform.h -@@ -0,0 +1,6 @@ -+#ifndef PANEL_MNT_POCKET_REFORM_H -+#define PANEL_MNT_POCKET_REFORM_H -+ -+int mnt_pocket_reform_get_panel_version(void); -+ -+#endif diff --git a/gnu/packages/patches/reform/imx8mp-mnt-reform2/0001-sn65dsi86-use-hs-clock-of-samsung-dsim-host-directly.patch b/gnu/packages/patches/reform/imx8mp-mnt-reform2/0001-sn65dsi86-use-hs-clock-of-samsung-dsim-host-directly.patch deleted file mode 100644 index 0bd34fc61d..0000000000 --- a/gnu/packages/patches/reform/imx8mp-mnt-reform2/0001-sn65dsi86-use-hs-clock-of-samsung-dsim-host-directly.patch +++ /dev/null @@ -1,45 +0,0 @@ -commit d9686ba780834f5d728bda8aff9dc585f51380a7 -Author: Lukas F. Hartmann <lukas@mntre.com> -Date: Thu May 30 14:46:50 2024 +0200 - - ti-sn65dsi86: use HS clock of samsung dsim host directly - ---- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c -+++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c -@@ -186,6 +186,7 @@ struct ti_sn65dsi86 { - struct drm_bridge *next_bridge; - struct gpio_desc *enable_gpio; - struct regulator_bulk_data supplies[SN_REGULATOR_SUPPLY_NUM]; -+ u32 hs_rate_hz; - int dp_lanes; - u8 ln_assign; - u8 ln_polrs; -@@ -288,7 +289,11 @@ static void ti_sn_bridge_set_refclk_freq - refclk_lut_size = ARRAY_SIZE(ti_sn_bridge_refclk_lut); - clk_prepare_enable(pdata->refclk); - } else { -- refclk_rate = ti_sn_bridge_get_dsi_freq(pdata) * 1000; -+ if (pdata->hs_rate_hz) -+ refclk_rate = pdata->hs_rate_hz; -+ else -+ refclk_rate = ti_sn_bridge_get_dsi_freq(pdata) * 1000; -+ - refclk_lut = ti_sn_bridge_dsiclk_lut; - refclk_lut_size = ARRAY_SIZE(ti_sn_bridge_dsiclk_lut); - } -@@ -718,6 +723,15 @@ static int ti_sn_attach_host(struct auxi - dsi->format = MIPI_DSI_FMT_RGB888; - dsi->mode_flags = MIPI_DSI_MODE_VIDEO; - -+ /* For i.MX8MP / Samsung DSIM Host, don't guess the HS rate, but read it from DTS */ -+ if (of_device_is_compatible(pdata->host_node, "fsl,imx8mp-mipi-dsim")) { -+ unsigned int hs_hz; -+ if (!of_property_read_u32(pdata->host_node, "samsung,burst-clock-frequency", &hs_hz)) { -+ pdata->hs_rate_hz = hs_hz / 2; -+ DRM_DEV_INFO(pdata->dev, "HS clock set to %u from i.MX8MP / Samsung DSIM.\n", pdata->hs_rate_hz); -+ } -+ } -+ - /* check if continuous dsi clock is required or not */ - pm_runtime_get_sync(dev); - regmap_read(pdata->regmap, SN_DPPLL_SRC_REG, &val); diff --git a/gnu/packages/patches/reform/imx8mp-mnt-reform2/0002-lcdif-dont-exceed-desired-pixel-clock.patch b/gnu/packages/patches/reform/imx8mp-mnt-reform2/0002-lcdif-dont-exceed-desired-pixel-clock.patch deleted file mode 100644 index efa9e8f148..0000000000 --- a/gnu/packages/patches/reform/imx8mp-mnt-reform2/0002-lcdif-dont-exceed-desired-pixel-clock.patch +++ /dev/null @@ -1,32 +0,0 @@ -commit 776721d5e1a6996054829c2b5f903a34b19a044c -Author: Lukas F. Hartmann <lukas@mntre.com> -Date: Thu May 30 14:50:52 2024 +0200 - - lcdif: don't exceed desired pixel clock - -diff --git a/drivers/gpu/drm/mxsfb/lcdif_kms.c b/drivers/gpu/drm/mxsfb/lcdif_kms.c -index 2541d2de..6820f3f7 100644 ---- a/drivers/gpu/drm/mxsfb/lcdif_kms.c -+++ b/drivers/gpu/drm/mxsfb/lcdif_kms.c -@@ -537,8 +537,19 @@ static void lcdif_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_display_mode *m = &lcdif->crtc.state->adjusted_mode; - struct drm_device *drm = lcdif->drm; - dma_addr_t paddr; -- -- clk_set_rate(lcdif->clk, m->clock * 1000); -+ u32 actual; -+ u32 mult = 1000; -+ -+ /* Get as close to the desired pixel clock, but do not -+ exceed it--otherwise, MIPI-DSI links fail */ -+ do { -+ clk_set_rate(lcdif->clk, m->crtc_clock * mult); -+ actual = clk_get_rate(lcdif->clk); -+ if (actual / 1000 > m->crtc_clock && mult > 10) -+ mult -= 10; -+ else -+ break; -+ } while (1); - - pm_runtime_get_sync(drm->dev); - diff --git a/gnu/packages/patches/reform/imx8mq-mnt-reform2/0001-nwl-dsi-fixup-mode-only-for-LCDIF-input-not-DCSS.patch b/gnu/packages/patches/reform/imx8mq-mnt-reform2/0001-nwl-dsi-fixup-mode-only-for-LCDIF-input-not-DCSS.patch deleted file mode 100644 index c25600bff9..0000000000 --- a/gnu/packages/patches/reform/imx8mq-mnt-reform2/0001-nwl-dsi-fixup-mode-only-for-LCDIF-input-not-DCSS.patch +++ /dev/null @@ -1,37 +0,0 @@ -From e142b3299f5cf105f41b40df86973fa50f9a0fa1 Mon Sep 17 00:00:00 2001 -From: "Lukas F. Hartmann" <lukas@mntre.com> -Date: Wed, 7 Sep 2022 06:20:37 +0200 -Subject: [PATCH 1/5] nwl-dsi-fixup-mode-only-for-LCDIF-input-not-DCSS - ---- - drivers/gpu/drm/bridge/nwl-dsi.c | 13 ++++++++++--- - 1 file changed, 10 insertions(+), 3 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c -index 4a5f5c4f5dcc..fa7ebaba15ca 100644 ---- a/drivers/gpu/drm/bridge/nwl-dsi.c -+++ b/drivers/gpu/drm/bridge/nwl-dsi.c -@@ -822,10 +822,17 @@ static int nwl_dsi_bridge_atomic_check(struct drm_bridge *bridge, - struct drm_connector_state *conn_state) - { - struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode; -+ struct device_node *remote; -+ struct nwl_dsi *dsi = bridge_to_dsi(bridge); - -- /* At least LCDIF + NWL needs active high sync */ -- adjusted_mode->flags |= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC); -- adjusted_mode->flags &= ~(DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC); -+ remote = of_graph_get_remote_node(dsi->dev->of_node, 0, -+ NWL_DSI_ENDPOINT_LCDIF); -+ -+ if (remote) { -+ /* At least LCDIF + NWL needs active high sync */ -+ adjusted_mode->flags |= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC); -+ adjusted_mode->flags &= ~(DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC); -+ } - - /* - * Do a full modeset if crtc_state->active is changed to be true. --- -2.40.0 - diff --git a/gnu/packages/patches/reform/imx8mq-mnt-reform2/0002-pci-imx6-add-support-for-internal-refclk-imx8mq.patch b/gnu/packages/patches/reform/imx8mq-mnt-reform2/0002-pci-imx6-add-support-for-internal-refclk-imx8mq.patch deleted file mode 100644 index d3bfa95491..0000000000 --- a/gnu/packages/patches/reform/imx8mq-mnt-reform2/0002-pci-imx6-add-support-for-internal-refclk-imx8mq.patch +++ /dev/null @@ -1,86 +0,0 @@ -From a206ec2a1b5cce523c2345bae73271148eaa5f72 Mon Sep 17 00:00:00 2001 -From: "Lukas F. Hartmann" <lukas@mntre.com> -Date: Sat, 22 Oct 2022 17:11:19 +0200 -Subject: [PATCH 2/5] pci-imx6-add-support-for-internal-refclk-imx8mq - ---- - drivers/pci/controller/dwc/pci-imx6.c | 44 +++++++++++++++++++++++++-- - 1 file changed, 42 insertions(+), 2 deletions(-) - ---- a/drivers/pci/controller/dwc/pci-imx6.c -+++ b/drivers/pci/controller/dwc/pci-imx6.c -@@ -107,6 +107,7 @@ struct imx_pcie_drvdata { - struct imx_pcie { - struct dw_pcie *pci; - struct gpio_desc *reset_gpiod; -+ bool internal_refclk; - bool link_is_up; - struct clk_bulk_data clks[IMX_PCIE_MAX_CLKS]; - struct regmap *iomuxc_gpr; -@@ -213,6 +214,40 @@ static int imx95_pcie_init_phy(struct im - return 0; - } - -+#define IMX8MQ_ANA_PLLOUT_REG 0x74 -+#define IMX8MQ_ANA_PLLOUT_CKE BIT(4) -+#define IMX8MQ_ANA_PLLOUT_SEL_MASK 0xF -+#define IMX8MQ_ANA_PLLOUT_SEL_SYSPLL1 0xB -+#define IMX8MQ_ANA_PLLOUT_DIV_REG 0x7C -+#define IMX8MQ_ANA_PLLOUT_SYSPLL1_DIV 0x7 -+ -+static void imx_pcie_enable_internal_refclk(void) -+{ -+ uint32_t val; -+ struct device_node* np; -+ void __iomem *base; -+ -+ np = of_find_compatible_node(NULL, NULL, -+ "fsl,imx8mq-anatop"); -+ base = of_iomap(np, 0); -+ WARN_ON(!base); -+ -+ val = readl(base + IMX8MQ_ANA_PLLOUT_REG); -+ val &= ~IMX8MQ_ANA_PLLOUT_SEL_MASK; -+ val |= IMX8MQ_ANA_PLLOUT_SEL_SYSPLL1; -+ writel(val, base + IMX8MQ_ANA_PLLOUT_REG); -+ /* SYS_PLL1 is 800M, PCIE REF CLK is 100M */ -+ val = readl(base + IMX8MQ_ANA_PLLOUT_DIV_REG); -+ val |= IMX8MQ_ANA_PLLOUT_SYSPLL1_DIV; -+ writel(val, base + IMX8MQ_ANA_PLLOUT_DIV_REG); -+ -+ val = readl(base + IMX8MQ_ANA_PLLOUT_REG); -+ val |= IMX8MQ_ANA_PLLOUT_CKE; -+ writel(val, base + IMX8MQ_ANA_PLLOUT_REG); -+ -+ usleep_range(9000,10000); -+} -+ - static void imx_pcie_configure_type(struct imx_pcie *imx_pcie) - { - const struct imx_pcie_drvdata *drvdata = imx_pcie->drvdata; -@@ -362,11 +397,15 @@ static int pcie_phy_write(struct imx_pc - - static int imx8mq_pcie_init_phy(struct imx_pcie *imx_pcie) - { -+ if (imx_pcie->internal_refclk) -+ imx_pcie_enable_internal_refclk(); -+ - /* TODO: Currently this code assumes external oscillator is being used */ - regmap_update_bits(imx_pcie->iomuxc_gpr, - imx_pcie_grp_offset(imx_pcie), - IMX8MQ_GPR_PCIE_REF_USE_PAD, -- IMX8MQ_GPR_PCIE_REF_USE_PAD); -+ (imx_pcie->internal_refclk ? -+ 0 : IMX8MQ_GPR_PCIE_REF_USE_PAD)); - /* - * Regarding the datasheet, the PCIE_VPH is suggested to be 1.8V. If the PCIE_VPH is - * supplied by 3.3V, the VREG_BYPASS should be cleared to zero. -@@ -1320,6 +1359,8 @@ static int imx_pcie_probe(struct platfo - - switch (imx_pcie->drvdata->variant) { - case IMX8MQ: -+ imx_pcie->internal_refclk = of_property_read_bool(node, "internal-refclk"); -+ break; - case IMX8MQ_EP: - if (dbi_base->start == IMX8MQ_PCIE2_BASE_ADDR) - imx_pcie->controller_id = 1; diff --git a/gnu/packages/patches/reform/imx8mq-mnt-reform2/0003-lcdif-fix-pcie-interference.patch b/gnu/packages/patches/reform/imx8mq-mnt-reform2/0003-lcdif-fix-pcie-interference.patch deleted file mode 100644 index e5b37333f3..0000000000 --- a/gnu/packages/patches/reform/imx8mq-mnt-reform2/0003-lcdif-fix-pcie-interference.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 325b2c0798ad9ed5529f225488576175aa360466 Mon Sep 17 00:00:00 2001 -From: "Lukas F. Hartmann" <lukas@mntre.com> -Date: Wed, 7 Sep 2022 06:23:35 +0200 -Subject: [PATCH 3/5] lcdif-fix-pcie-interference - ---- - drivers/gpu/drm/mxsfb/mxsfb_kms.c | 34 ++++++++++++++++++++++++++++++- - 1 file changed, 33 insertions(+), 1 deletion(-) - ---- a/drivers/gpu/drm/mxsfb/mxsfb_kms.c -+++ b/drivers/gpu/drm/mxsfb/mxsfb_kms.c -@@ -303,7 +303,7 @@ static void mxsfb_crtc_mode_set_nofb(str - - mxsfb_set_formats(mxsfb, bus_format); - -- clk_set_rate(mxsfb->clk, m->crtc_clock * 1000); -+ clk_set_rate(mxsfb->clk, m->crtc_clock * 660); - - mxsfb_set_mode(mxsfb, bus_flags); - } -@@ -671,12 +671,44 @@ static const uint64_t mxsfb_modifiers[] - * Initialization - */ - -+void imx8mq_pcie_qos_for_lcdif(void) -+{ -+ void __iomem *qosc = ioremap(0x307f0000, 0x2100); -+ // clock and unlock QoSC registers -+ writel(0x0, qosc); -+ writel(0x1, qosc); -+ writel(0x0, qosc+0x60); -+ -+ // limit number of outstanding transactions for PCIe1 -+ writel(0x0, qosc+0x1000); -+ writel(0x1, qosc+0x1000); -+ writel(0x01010100, qosc+0x1050); -+ writel(0x01010100, qosc+0x1060); -+ writel(0x01010100, qosc+0x1070); -+ writel(0x1, qosc+0x1000); -+ -+ // limit number of outstanding transactions for PCIe2 -+ writel(0x0, qosc+0x2000); -+ writel(0x1, qosc+0x2000); -+ writel(0x01010100, qosc+0x2050); -+ writel(0x01010100, qosc+0x2060); -+ writel(0x01010100, qosc+0x2070); -+ writel(0x1, qosc+0x2000); -+ -+ iounmap(qosc); -+} -+ - int mxsfb_kms_init(struct mxsfb_drm_private *mxsfb) - { - struct drm_encoder *encoder = &mxsfb->encoder; - struct drm_crtc *crtc = &mxsfb->crtc; - int ret; - -+ /* -+ FIXME Workaround to fix PCIe interfering with LCDIF refresh (MNT Reform) -+ */ -+ imx8mq_pcie_qos_for_lcdif(); -+ - drm_plane_helper_add(&mxsfb->planes.primary, - &mxsfb_plane_primary_helper_funcs); - ret = drm_universal_plane_init(mxsfb->drm, &mxsfb->planes.primary, 1, ---- a/drivers/gpu/drm/mxsfb/mxsfb_drv.h -+++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.h -@@ -58,6 +58,8 @@ to_mxsfb_drm_private(struct drm_device * - void mxsfb_enable_axi_clk(struct mxsfb_drm_private *mxsfb); - void mxsfb_disable_axi_clk(struct mxsfb_drm_private *mxsfb); - -+void imx8mq_pcie_qos_for_lcdif(void); -+ - int mxsfb_kms_init(struct mxsfb_drm_private *mxsfb); - - #endif /* __MXSFB_DRV_H__ */ diff --git a/gnu/packages/patches/reform/imx8mq-mnt-reform2/0004-mnt4002-imx-gpcv2-wake-smccc.patch.patch b/gnu/packages/patches/reform/imx8mq-mnt-reform2/0004-mnt4002-imx-gpcv2-wake-smccc.patch.patch deleted file mode 100644 index 83cf4e29bc..0000000000 --- a/gnu/packages/patches/reform/imx8mq-mnt-reform2/0004-mnt4002-imx-gpcv2-wake-smccc.patch.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 1636b47d4f5a89cc1791d5b2a29a0443713b4f93 Mon Sep 17 00:00:00 2001 -From: "Lukas F. Hartmann" <lukas@mntre.com> -Date: Wed, 7 Sep 2022 06:24:04 +0200 -Subject: [PATCH 4/5] mnt4002-imx-gpcv2-wake-smccc.patch - ---- - drivers/irqchip/irq-imx-gpcv2.c | 24 ++++++++++++++++++++++++ - 1 file changed, 24 insertions(+) - -diff --git a/drivers/irqchip/irq-imx-gpcv2.c b/drivers/irqchip/irq-imx-gpcv2.c -index 8a0e82067924..75196a0d8745 100644 ---- a/drivers/irqchip/irq-imx-gpcv2.c -+++ b/drivers/irqchip/irq-imx-gpcv2.c -@@ -3,6 +3,7 @@ - * Copyright (C) 2015 Freescale Semiconductor, Inc. - */ - -+#include <linux/arm-smccc.h> - #include <linux/of_address.h> - #include <linux/of_irq.h> - #include <linux/slab.h> -@@ -17,6 +18,13 @@ - #define GPC_IMR1_CORE2 0x1c0 - #define GPC_IMR1_CORE3 0x1d0 - -+#define FSL_SIP_GPC 0xC2000000 -+#define FSL_SIP_CONFIG_GPC_MASK 0x00 -+#define FSL_SIP_CONFIG_GPC_UNMASK 0x01 -+#define FSL_SIP_CONFIG_GPC_SET_WAKE 0x02 -+#define FSL_SIP_CONFIG_GPC_PM_DOMAIN 0x03 -+#define FSL_SIP_CONFIG_GPC_SET_AFF 0x04 -+#define FSL_SIP_CONFIG_GPC_CORE_WAKE 0x05 - - struct gpcv2_irqchip_data { - struct raw_spinlock rlock; -@@ -76,12 +84,17 @@ static int imx_gpcv2_irq_set_wake(struct irq_data *d, unsigned int on) - unsigned int idx = d->hwirq / 32; - unsigned long flags; - u32 mask, val; -+ struct arm_smccc_res res; - - raw_spin_lock_irqsave(&cd->rlock, flags); - mask = BIT(d->hwirq % 32); - val = cd->wakeup_sources[idx]; - - cd->wakeup_sources[idx] = on ? (val & ~mask) : (val | mask); -+ -+ // save wakeup config in vendor tf-a -+ arm_smccc_smc(FSL_SIP_GPC, FSL_SIP_CONFIG_GPC_SET_WAKE, d->hwirq, on, 0, 0, 0, 0, &res); -+ - raw_spin_unlock_irqrestore(&cd->rlock, flags); - - /* -@@ -97,6 +110,7 @@ static void imx_gpcv2_irq_unmask(struct irq_data *d) - struct gpcv2_irqchip_data *cd = d->chip_data; - void __iomem *reg; - u32 val; -+ struct arm_smccc_res res; - - raw_spin_lock(&cd->rlock); - reg = gpcv2_idx_to_reg(cd, d->hwirq / 32); -@@ -105,6 +119,10 @@ static void imx_gpcv2_irq_unmask(struct irq_data *d) - writel_relaxed(val, reg); - raw_spin_unlock(&cd->rlock); - -+ // call into vendor tf-a -+ //arm_smccc_smc(FSL_SIP_GPC, FSL_SIP_CONFIG_GPC_UNMASK, -+ // d->hwirq, 0, 0, 0, 0, 0, &res); -+ - irq_chip_unmask_parent(d); - } - -@@ -113,12 +131,18 @@ static void imx_gpcv2_irq_mask(struct irq_data *d) - struct gpcv2_irqchip_data *cd = d->chip_data; - void __iomem *reg; - u32 val; -+ struct arm_smccc_res res; - - raw_spin_lock(&cd->rlock); - reg = gpcv2_idx_to_reg(cd, d->hwirq / 32); - val = readl_relaxed(reg); - val |= BIT(d->hwirq % 32); - writel_relaxed(val, reg); -+ -+ // call into vendor tf-a -+ //arm_smccc_smc(FSL_SIP_GPC, FSL_SIP_CONFIG_GPC_MASK, -+ // d->hwirq, 0, 0, 0, 0, 0, &res); -+ - raw_spin_unlock(&cd->rlock); - - irq_chip_mask_parent(d); --- -2.40.0 - diff --git a/gnu/packages/patches/reform/imx8mq-mnt-reform2/v19_20241126_sandor_yu_initial_support_cadence_mhdp8501_hdmi_dp_for_i_mx8mq.mbx b/gnu/packages/patches/reform/imx8mq-mnt-reform2/v19_20241126_sandor_yu_initial_support_cadence_mhdp8501_hdmi_dp_for_i_mx8mq.mbx deleted file mode 100644 index 9890ba4e08..0000000000 --- a/gnu/packages/patches/reform/imx8mq-mnt-reform2/v19_20241126_sandor_yu_initial_support_cadence_mhdp8501_hdmi_dp_for_i_mx8mq.mbx +++ /dev/null @@ -1,6137 +0,0 @@ -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH v19 1/8] drm: bridge: Cadence: Create MHDP helper driver -From: Sandor Yu <Sandor.yu@nxp.com> -Date: Tue, 26 Nov 2024 22:11:46 +0800 -Message-Id: <4a6e511fed26289eeb63109882f7657ab5d4415d.1732627815.git.Sandor.yu@nxp.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -Mailbox access functions in MHDP8546 will be share to other MHDP driver -and Cadence HDP-TX HDMI/DP PHY drivers. - -Create a new MHDP helper driver and move all mailbox access functions into. -According the mailbox access sequence and type of security. -Six mailbox access API functions are introduced. -Three APIs for non-secure mailbox access: - - cdns_mhdp_mailbox_send() - - cdns_mhdp_mailbox_send_recv() - - cdns_mhdp_mailbox_send_recv_multi() -The other three APIs for secure mailbox access: - - cdns_mhdp_secure_mailbox_send() - - cdns_mhdp_secure_mailbox_send_recv() - - cdns_mhdp_secure_mailbox_send_recv_multi() - -All MHDP commands that need to be passed through the mailbox -have been rewritten using those new API functions. - -The register read/write and DP DPCD read/write command functions -are also included in this new helper driver. - -Function cdns_mhdp_reg_write() is renamed to cdns_mhdp_dp_reg_write(), -because it use the DPTX command ID DPTX_WRITE_REGISTER. -New cdns_mhdp_reg_write() is added with the general command ID -GENERAL_REGISTER_WRITE. - -Signed-off-by: Sandor Yu <Sandor.yu@nxp.com> ---- -v18->v19: -- Use guard(mutex) -- Add kerneldocs for all new APIs. -- Detail comments for mailbox access specific case. -- Remove cdns_mhdp_dp_reg_write() because it is not needed by driver now. - -v17->v18: -- Create three ordinary mailbox access APIs - cdns_mhdp_mailbox_send - cdns_mhdp_mailbox_send_recv - cdns_mhdp_mailbox_send_recv_multi -- Create three secure mailbox access APIs - cdns_mhdp_secure_mailbox_send - cdns_mhdp_secure_mailbox_send_recv - cdns_mhdp_secure_mailbox_send_recv_multi -- MHDP8546 DP and HDCP commands that need access mailbox are rewrited - with above 6 API functions. - -v16->v17: -- Replaces the local mutex mbox_mutex with a global mutex mhdp_mailbox_mutex - -v12->v16: - *No change. - - drivers/gpu/drm/bridge/cadence/Kconfig | 8 + - drivers/gpu/drm/bridge/cadence/Makefile | 1 + - .../gpu/drm/bridge/cadence/cdns-mhdp-helper.c | 565 ++++++++++++++++++ - .../drm/bridge/cadence/cdns-mhdp8546-core.c | 487 +++------------ - .../drm/bridge/cadence/cdns-mhdp8546-core.h | 47 +- - .../drm/bridge/cadence/cdns-mhdp8546-hdcp.c | 236 +------- - .../drm/bridge/cadence/cdns-mhdp8546-hdcp.h | 18 +- - include/drm/bridge/cdns-mhdp-helper.h | 129 ++++ - 8 files changed, 812 insertions(+), 679 deletions(-) - create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp-helper.c - create mode 100644 include/drm/bridge/cdns-mhdp-helper.h - -diff --git a/drivers/gpu/drm/bridge/cadence/Kconfig b/drivers/gpu/drm/bridge/cadence/Kconfig -index cced81633ddcd..1b315593a6d73 100644 ---- a/drivers/gpu/drm/bridge/cadence/Kconfig -+++ b/drivers/gpu/drm/bridge/cadence/Kconfig -@@ -21,6 +21,13 @@ config DRM_CDNS_DSI_J721E - the routing of the DSS DPI signal to the Cadence DSI. - endif - -+config CDNS_MHDP_HELPER -+ tristate "Cadence MHDP Helper driver" -+ help -+ Enable Cadence MHDP helpers for mailbox, HDMI and DP. -+ This driver provides a foundational layer of mailbox communication for -+ various Cadence MHDP IP implementations, such as HDMI and DisplayPort. -+ - config DRM_CDNS_MHDP8546 - tristate "Cadence DPI/DP bridge" - select DRM_DISPLAY_DP_HELPER -@@ -28,6 +35,7 @@ config DRM_CDNS_MHDP8546 - select DRM_DISPLAY_HELPER - select DRM_KMS_HELPER - select DRM_PANEL_BRIDGE -+ select CDNS_MHDP_HELPER - depends on OF - help - Support Cadence DPI to DP bridge. This is an internal -diff --git a/drivers/gpu/drm/bridge/cadence/Makefile b/drivers/gpu/drm/bridge/cadence/Makefile -index c95fd5b81d137..087dc074820d7 100644 ---- a/drivers/gpu/drm/bridge/cadence/Makefile -+++ b/drivers/gpu/drm/bridge/cadence/Makefile -@@ -2,6 +2,7 @@ - obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o - cdns-dsi-y := cdns-dsi-core.o - cdns-dsi-$(CONFIG_DRM_CDNS_DSI_J721E) += cdns-dsi-j721e.o -+obj-$(CONFIG_CDNS_MHDP_HELPER) += cdns-mhdp-helper.o - obj-$(CONFIG_DRM_CDNS_MHDP8546) += cdns-mhdp8546.o - cdns-mhdp8546-y := cdns-mhdp8546-core.o cdns-mhdp8546-hdcp.o - cdns-mhdp8546-$(CONFIG_DRM_CDNS_MHDP8546_J721E) += cdns-mhdp8546-j721e.o -diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp-helper.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-helper.c -new file mode 100644 -index 0000000000000..93b78f65dd8b8 ---- /dev/null -+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-helper.c -@@ -0,0 +1,565 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (C) 2023, 2024 NXP Semiconductor, Inc. -+ * -+ */ -+#include <drm/bridge/cdns-mhdp-helper.h> -+#include <linux/dev_printk.h> -+#include <linux/module.h> -+ -+/* Protects mailbox communications with the firmware */ -+static DEFINE_MUTEX(mhdp_mailbox_mutex); -+ -+/* Mailbox helper functions */ -+static int mhdp_mailbox_read(void __iomem *regs) -+{ -+ int ret, empty; -+ -+ WARN_ON(!mutex_is_locked(&mhdp_mailbox_mutex)); -+ -+ ret = readx_poll_timeout(readl, regs + CDNS_MAILBOX_EMPTY, -+ empty, !empty, MAILBOX_RETRY_US, -+ MAILBOX_TIMEOUT_US); -+ if (ret < 0) -+ return ret; -+ -+ return readl(regs + CDNS_MAILBOX_RX_DATA) & 0xff; -+} -+ -+static int mhdp_mailbox_write(void __iomem *regs, u8 val) -+{ -+ int ret, full; -+ -+ WARN_ON(!mutex_is_locked(&mhdp_mailbox_mutex)); -+ -+ ret = readx_poll_timeout(readl, regs + CDNS_MAILBOX_FULL, -+ full, !full, MAILBOX_RETRY_US, -+ MAILBOX_TIMEOUT_US); -+ if (ret < 0) -+ return ret; -+ -+ writel(val, regs + CDNS_MAILBOX_TX_DATA); -+ -+ return 0; -+} -+ -+static int mhdp_mailbox_recv_header(void __iomem *regs, -+ u8 module_id, u8 opcode, -+ u16 req_size) -+{ -+ u32 mbox_size, i; -+ u8 header[4]; -+ int ret; -+ -+ /* read the header of the message */ -+ for (i = 0; i < sizeof(header); i++) { -+ ret = mhdp_mailbox_read(regs); -+ if (ret < 0) -+ return ret; -+ -+ header[i] = ret; -+ } -+ -+ mbox_size = get_unaligned_be16(header + 2); -+ -+ /* -+ * If the message in mailbox is not what we want, we need to -+ * clear the mailbox by reading its contents. -+ * Response data length for HDCP TX HDCP_TRAN_IS_REC_ID_VALID depend on case. -+ */ -+ if (opcode != header[0] || -+ module_id != header[1] || -+ (opcode != HDCP_TRAN_IS_REC_ID_VALID && req_size != mbox_size)) { -+ for (i = 0; i < mbox_size; i++) -+ if (mhdp_mailbox_read(regs) < 0) -+ break; -+ -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int mhdp_mailbox_recv_data(void __iomem *regs, -+ u8 *buff, u16 buff_size) -+{ -+ u32 i; -+ int ret; -+ -+ for (i = 0; i < buff_size; i++) { -+ ret = mhdp_mailbox_read(regs); -+ if (ret < 0) -+ return ret; -+ -+ buff[i] = ret; -+ } -+ -+ return 0; -+} -+ -+static int mhdp_mailbox_send(void __iomem *regs, u8 module_id, -+ u8 opcode, u16 size, u8 *message) -+{ -+ u8 header[4]; -+ int ret, i; -+ -+ header[0] = opcode; -+ header[1] = module_id; -+ put_unaligned_be16(size, header + 2); -+ -+ for (i = 0; i < sizeof(header); i++) { -+ ret = mhdp_mailbox_write(regs, header[i]); -+ if (ret) -+ return ret; -+ } -+ -+ for (i = 0; i < size; i++) { -+ ret = mhdp_mailbox_write(regs, message[i]); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+/** -+ * cdns_mhdp_mailbox_send - Sends a message via the MHDP mailbox. -+ * -+ * This function sends a message via the MHDP mailbox. -+ * -+ * @base: Pointer to the CDNS MHDP base structure. -+ * @module_id: ID of the module to send the message to. -+ * @opcode: Operation code of the message. -+ * @size: Size of the message data. -+ * @message: Pointer to the message data. -+ * -+ * Returns: 0 on success, negative error code on failure. -+ */ -+int cdns_mhdp_mailbox_send(struct cdns_mhdp_base *base, u8 module_id, -+ u8 opcode, u16 size, u8 *message) -+{ -+ guard(mutex)(&mhdp_mailbox_mutex); -+ -+ return mhdp_mailbox_send(base->regs, module_id, opcode, size, message); -+} -+EXPORT_SYMBOL_GPL(cdns_mhdp_mailbox_send); -+ -+/** -+ * cdns_mhdp_mailbox_send_recv - Sends a message and receives a response. -+ * -+ * This function sends a message via the mailbox and then receives a response. -+ * -+ * @base: Pointer to the CDNS MHDP base structure. -+ * @module_id: ID of the module to send the message to. -+ * @opcode: Operation code of the message. -+ * @msg_size: Size of the message data. -+ * @msg: Pointer to the message data. -+ * @resp_size: Size of the response buffer. -+ * @resp: Pointer to the response buffer. -+ * -+ * Returns: 0 on success, negative error code on failure. -+ */ -+int cdns_mhdp_mailbox_send_recv(struct cdns_mhdp_base *base, -+ u8 module_id, u8 opcode, -+ u16 msg_size, u8 *msg, -+ u16 resp_size, u8 *resp) -+{ -+ int ret; -+ -+ guard(mutex)(&mhdp_mailbox_mutex); -+ -+ ret = mhdp_mailbox_send(base->regs, module_id, -+ opcode, msg_size, msg); -+ if (ret) { -+ dev_err(base->dev, "ModuleID=%d, CMD=%d send failed: %d\n", -+ module_id, opcode, ret); -+ return ret; -+ } -+ -+ ret = mhdp_mailbox_recv_header(base->regs, module_id, -+ opcode, resp_size); -+ if (ret) { -+ dev_err(base->dev, "ModuleID=%d, CMD=%d recv header failed: %d\n", -+ module_id, opcode, ret); -+ return ret; -+ } -+ -+ ret = mhdp_mailbox_recv_data(base->regs, resp, resp_size); -+ if (ret) -+ dev_err(base->dev, "ModuleID=%d, CMD=%d recv data failed: %d\n", -+ module_id, opcode, ret); -+ return ret; -+} -+EXPORT_SYMBOL_GPL(cdns_mhdp_mailbox_send_recv); -+ -+/** -+ * cdns_mhdp_mailbox_send_recv_multi - Sends a message and receives multiple responses. -+ * -+ * This function sends a message to a specified module via the MHDP mailbox and -+ * then receives multiple responses from the module. -+ * -+ * @param base: Pointer to the CDNS MHDP base structure. -+ * @param module_id: ID of the module to send the message to. -+ * @param opcode: Operation code of the message. -+ * @param msg_size: Size of the message data. -+ * @param msg: Pointer to the message data. -+ * @param opcode_resp: Operation code of the response. -+ * @param resp1_size: Size of the first response buffer. -+ * @param resp1: Pointer to the first response buffer. -+ * @param resp2_size: Size of the second response buffer. -+ * @param resp2: Pointer to the second response buffer. -+ * -+ * Returns: 0 on success, negative error code on failure. -+ */ -+int cdns_mhdp_mailbox_send_recv_multi(struct cdns_mhdp_base *base, -+ u8 module_id, u8 opcode, -+ u16 msg_size, u8 *msg, -+ u8 opcode_resp, -+ u16 resp1_size, u8 *resp1, -+ u16 resp2_size, u8 *resp2) -+{ -+ int ret; -+ -+ guard(mutex)(&mhdp_mailbox_mutex); -+ -+ ret = mhdp_mailbox_send(base->regs, module_id, -+ opcode, msg_size, msg); -+ if (ret) { -+ dev_err(base->dev, "ModuleID=%d, CMD=%d send failed: %d\n", -+ module_id, opcode, ret); -+ return ret; -+ } -+ -+ ret = mhdp_mailbox_recv_header(base->regs, module_id, opcode_resp, -+ resp1_size + resp2_size); -+ if (ret) { -+ dev_err(base->dev, "ModuleID=%d, Resp_CMD=%d recv header failed: %d\n", -+ module_id, opcode_resp, ret); -+ return ret; -+ } -+ -+ ret = mhdp_mailbox_recv_data(base->regs, resp1, resp1_size); -+ if (ret) { -+ dev_err(base->dev, "ModuleID=%d, Resp_CMD=%d recv data1 failed: %d\n", -+ module_id, opcode_resp, ret); -+ return ret; -+ } -+ -+ ret = mhdp_mailbox_recv_data(base->regs, resp2, resp2_size); -+ if (ret) -+ dev_err(base->dev, "ModuleID=%d, Resp_CMD=%d recv data1 failed: %d\n", -+ module_id, opcode_resp, ret); -+ return ret; -+} -+EXPORT_SYMBOL_GPL(cdns_mhdp_mailbox_send_recv_multi); -+ -+/** -+ * cdns_mhdp_secure_mailbox_send - Sends a secure message via the mailbox. -+ * -+ * This function sends a secure message to a specified module via the MHDP mailbox. -+ * -+ * @param base: Pointer to the CDNS MHDP base structure. -+ * @param module_id: ID of the module to send the message to. -+ * @param opcode: Operation code of the message. -+ * @param size: Size of the message data. -+ * @param message: Pointer to the message data. -+ * -+ * Returns: 0 on success, negative error code on failure. -+ */ -+int cdns_mhdp_secure_mailbox_send(struct cdns_mhdp_base *base, u8 module_id, -+ u8 opcode, u16 size, u8 *message) -+{ -+ guard(mutex)(&mhdp_mailbox_mutex); -+ -+ return mhdp_mailbox_send(base->sapb_regs, module_id, opcode, size, message); -+} -+EXPORT_SYMBOL_GPL(cdns_mhdp_secure_mailbox_send); -+ -+/** -+ * cdns_mhdp_secure_mailbox_send_recv - Sends a secure message and receives a response. -+ * -+ * This function sends a secure message to a specified module via the mailbox and -+ * then receives a response from the module. -+ * -+ * @param base: Pointer to the CDNS MHDP base structure. -+ * @param module_id: ID of the module to send the message to. -+ * @param opcode: Operation code of the message. -+ * @param msg_size: Size of the message data. -+ * @param msg: Pointer to the message data. -+ * @param resp_size: Size of the response buffer. -+ * @param resp: Pointer to the response buffer. -+ * -+ * Returns: 0 on success, negative error code on failure. -+ */ -+int cdns_mhdp_secure_mailbox_send_recv(struct cdns_mhdp_base *base, -+ u8 module_id, u8 opcode, -+ u16 msg_size, u8 *msg, -+ u16 resp_size, u8 *resp) -+{ -+ int ret; -+ -+ guard(mutex)(&mhdp_mailbox_mutex); -+ -+ ret = mhdp_mailbox_send(base->sapb_regs, module_id, -+ opcode, msg_size, msg); -+ if (ret) { -+ dev_err(base->dev, "ModuleID=%d, CMD=%d send failed: %d\n", -+ module_id, opcode, ret); -+ return ret; -+ } -+ -+ ret = mhdp_mailbox_recv_header(base->sapb_regs, module_id, -+ opcode, resp_size); -+ if (ret) { -+ dev_err(base->dev, "ModuleID=%d, CMD=%d recv header failed: %d\n", -+ module_id, opcode, ret); -+ return ret; -+ } -+ -+ ret = mhdp_mailbox_recv_data(base->sapb_regs, resp, resp_size); -+ if (ret) -+ dev_err(base->dev, "ModuleID=%d, CMD=%d recv data failed: %d\n", -+ module_id, opcode, ret); -+ return ret; -+} -+EXPORT_SYMBOL_GPL(cdns_mhdp_secure_mailbox_send_recv); -+ -+/** -+ * cdns_mhdp_secure_mailbox_send_recv_multi - Sends a secure message and receives multiple responses. -+ * -+ * This function sends a secure message to a specified module and receives multiple responses. -+ * -+ * @param base: Pointer to the CDNS MHDP base structure. -+ * @param module_id: ID of the module to send the message to. -+ * @param opcode: Operation code of the message. -+ * @param msg_size: Size of the message data. -+ * @param msg: Pointer to the message data. -+ * @param opcode_resp: Operation code of the response. -+ * @param resp1_size: Size of the first response buffer. -+ * @param resp1: Pointer to the first response buffer. -+ * @param resp2_size: Size of the second response buffer. -+ * @param resp2: Pointer to the second response buffer. -+ * -+ * Returns: 0 on success, negative error code on failure. -+ */ -+int cdns_mhdp_secure_mailbox_send_recv_multi(struct cdns_mhdp_base *base, -+ u8 module_id, u8 opcode, -+ u16 msg_size, u8 *msg, -+ u8 opcode_resp, -+ u16 resp1_size, u8 *resp1, -+ u16 resp2_size, u8 *resp2) -+{ -+ int ret; -+ -+ guard(mutex)(&mhdp_mailbox_mutex); -+ -+ ret = mhdp_mailbox_send(base->sapb_regs, module_id, -+ opcode, msg_size, msg); -+ if (ret) { -+ dev_err(base->dev, "ModuleID=%d, CMD=%d send failed: %d\n", -+ module_id, opcode, ret); -+ return ret; -+ } -+ -+ ret = mhdp_mailbox_recv_header(base->sapb_regs, module_id, -+ opcode_resp, -+ resp1_size + resp2_size); -+ if (ret) { -+ dev_err(base->dev, "ModuleID=%d, Resp_CMD=%d recv header failed: %d\n", -+ module_id, opcode_resp, ret); -+ return ret; -+ } -+ -+ ret = mhdp_mailbox_recv_data(base->sapb_regs, resp1, resp1_size); -+ if (ret) { -+ dev_err(base->dev, "ModuleID=%d, Resp_CMD=%d recv data1 failed: %d\n", -+ module_id, opcode_resp, ret); -+ return ret; -+ } -+ -+ /* -+ * Response data length for HDCP TX HDCP_TRAN_IS_REC_ID_VALID depend on -+ * the number of HDCP receivers in resp1[0]. -+ * 1 for regular case, more can be in repeater. -+ */ -+ if (module_id == MB_MODULE_ID_HDCP_TX && -+ opcode == HDCP_TRAN_IS_REC_ID_VALID) -+ ret = mhdp_mailbox_recv_data(base->sapb_regs, resp2, 5 * resp1[0]); -+ else -+ ret = mhdp_mailbox_recv_data(base->sapb_regs, resp2, resp2_size); -+ if (ret) -+ dev_err(base->dev, "ModuleID=%d, Resp_CMD=%d recv data2 failed: %d\n", -+ module_id, opcode_resp, ret); -+ return ret; -+} -+EXPORT_SYMBOL_GPL(cdns_mhdp_secure_mailbox_send_recv_multi); -+ -+/** -+ * cdns_mhdp_reg_read - Reads a general register value. -+ * -+ * This function reads the value from a general register -+ * using the mailbox. -+ * -+ * @param base: Pointer to the CDNS MHDP base structure. -+ * @param addr: Address of the register to read. -+ * @param value: Pointer to store the read value. -+ * -+ * Returns: 0 on success, negative error code on failure. -+ */ -+int cdns_mhdp_reg_read(struct cdns_mhdp_base *base, u32 addr, u32 *value) -+{ -+ u8 msg[4], resp[8]; -+ int ret; -+ -+ put_unaligned_be32(addr, msg); -+ -+ ret = cdns_mhdp_mailbox_send_recv(base, MB_MODULE_ID_GENERAL, -+ GENERAL_REGISTER_READ, -+ sizeof(msg), msg, sizeof(resp), resp); -+ if (ret) -+ goto out; -+ -+ /* Returned address value should be the same as requested */ -+ if (memcmp(msg, resp, sizeof(msg))) { -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ *value = get_unaligned_be32(resp + 4); -+out: -+ if (ret) { -+ dev_err(base->dev, "Failed to read register\n"); -+ *value = 0; -+ } -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(cdns_mhdp_reg_read); -+ -+/** -+ * cdns_mhdp_reg_write - Writes a value to a general register. -+ * -+ * This function writes a value to a general register using the mailbox. -+ * -+ * @param base: Pointer to the CDNS MHDP base structure. -+ * @param addr: Address of the register to write to. -+ * @param val: Value to write to the register. -+ * -+ * Returns: 0 on success, negative error code on failure. -+ */ -+int cdns_mhdp_reg_write(struct cdns_mhdp_base *base, u32 addr, u32 val) -+{ -+ u8 msg[8]; -+ -+ put_unaligned_be32(addr, msg); -+ put_unaligned_be32(val, msg + 4); -+ -+ return cdns_mhdp_mailbox_send(base, MB_MODULE_ID_GENERAL, -+ GENERAL_REGISTER_WRITE, -+ sizeof(msg), msg); -+} -+EXPORT_SYMBOL_GPL(cdns_mhdp_reg_write); -+ -+/* DPTX helper functions */ -+/** -+ * cdns_mhdp_dp_reg_write_bit - Writes a bit field to a DP register. -+ * -+ * This function writes a specific bit field within a DP register -+ * using the MHDP mailbox. -+ * -+ * @param base: Pointer to the CDNS MHDP base structure. -+ * @param addr: Address of the DP register. -+ * @param start_bit: Starting bit position within the register. -+ * @param bits_no: Number of bits to write. -+ * @param val: Value to write to the bit field. -+ * -+ * Returns: 0 on success, negative error code on failure. -+ */ -+int cdns_mhdp_dp_reg_write_bit(struct cdns_mhdp_base *base, u16 addr, -+ u8 start_bit, u8 bits_no, u32 val) -+{ -+ u8 field[8]; -+ -+ put_unaligned_be16(addr, field); -+ field[2] = start_bit; -+ field[3] = bits_no; -+ put_unaligned_be32(val, field + 4); -+ -+ return cdns_mhdp_mailbox_send(base, MB_MODULE_ID_DP_TX, -+ DPTX_WRITE_FIELD, sizeof(field), field); -+} -+EXPORT_SYMBOL_GPL(cdns_mhdp_dp_reg_write_bit); -+ -+/** -+ * cdns_mhdp_dpcd_read - Reads data from a DPCD register. -+ * -+ * This function reads data from a specified DPCD register -+ * using the MHDP mailbox. -+ * -+ * @param base: Pointer to the CDNS MHDP base structure. -+ * @param addr: Address of the DPCD register to read. -+ * @param data: Buffer to store the read data. -+ * @param len: Length of the data to read. -+ * -+ * Returns: 0 on success, negative error code on failure. -+ */ -+int cdns_mhdp_dpcd_read(struct cdns_mhdp_base *base, -+ u32 addr, u8 *data, u16 len) -+{ -+ u8 msg[5], reg[5]; -+ -+ put_unaligned_be16(len, msg); -+ put_unaligned_be24(addr, msg + 2); -+ -+ return cdns_mhdp_mailbox_send_recv_multi(base, -+ MB_MODULE_ID_DP_TX, -+ DPTX_READ_DPCD, -+ sizeof(msg), msg, -+ DPTX_READ_DPCD, -+ sizeof(reg), reg, -+ len, data); -+} -+EXPORT_SYMBOL_GPL(cdns_mhdp_dpcd_read); -+ -+/** -+ * cdns_mhdp_dpcd_write - Writes data to a DPCD register. -+ * -+ * This function writes data to a specified DPCD register -+ * using the MHDP mailbox. -+ * -+ * @param base: Pointer to the CDNS MHDP base structure. -+ * @param addr: Address of the DPCD register to write to. -+ * @param value: Value to write to the register. -+ * -+ * Returns: 0 on success, negative error code on failure. -+ */ -+int cdns_mhdp_dpcd_write(struct cdns_mhdp_base *base, u32 addr, u8 value) -+{ -+ u8 msg[6], reg[5]; -+ int ret; -+ -+ put_unaligned_be16(1, msg); -+ put_unaligned_be24(addr, msg + 2); -+ msg[5] = value; -+ -+ ret = cdns_mhdp_mailbox_send_recv(base, MB_MODULE_ID_DP_TX, -+ DPTX_WRITE_DPCD, -+ sizeof(msg), msg, sizeof(reg), reg); -+ if (ret) { -+ dev_err(base->dev, "dpcd write failed: %d\n", ret); -+ return ret; -+ } -+ -+ if (addr != get_unaligned_be24(reg + 2)) { -+ dev_err(base->dev, "Invalid response: expected address 0x%06x, got 0x%06x\n", -+ addr, get_unaligned_be24(reg + 2)); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(cdns_mhdp_dpcd_write); -+ -+MODULE_DESCRIPTION("Cadence MHDP Helper driver"); -+MODULE_AUTHOR("Sandor Yu <Sandor.yu@nxp.com>"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c -index 41f72d458487f..9ce1fcf7b88ea 100644 ---- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c -@@ -73,302 +73,18 @@ static void cdns_mhdp_bridge_hpd_disable(struct drm_bridge *bridge) - mhdp->regs + CDNS_APB_INT_MASK); - } - --static int cdns_mhdp_mailbox_read(struct cdns_mhdp_device *mhdp) --{ -- int ret, empty; -- -- WARN_ON(!mutex_is_locked(&mhdp->mbox_mutex)); -- -- ret = readx_poll_timeout(readl, mhdp->regs + CDNS_MAILBOX_EMPTY, -- empty, !empty, MAILBOX_RETRY_US, -- MAILBOX_TIMEOUT_US); -- if (ret < 0) -- return ret; -- -- return readl(mhdp->regs + CDNS_MAILBOX_RX_DATA) & 0xff; --} -- --static int cdns_mhdp_mailbox_write(struct cdns_mhdp_device *mhdp, u8 val) --{ -- int ret, full; -- -- WARN_ON(!mutex_is_locked(&mhdp->mbox_mutex)); -- -- ret = readx_poll_timeout(readl, mhdp->regs + CDNS_MAILBOX_FULL, -- full, !full, MAILBOX_RETRY_US, -- MAILBOX_TIMEOUT_US); -- if (ret < 0) -- return ret; -- -- writel(val, mhdp->regs + CDNS_MAILBOX_TX_DATA); -- -- return 0; --} -- --static int cdns_mhdp_mailbox_recv_header(struct cdns_mhdp_device *mhdp, -- u8 module_id, u8 opcode, -- u16 req_size) --{ -- u32 mbox_size, i; -- u8 header[4]; -- int ret; -- -- /* read the header of the message */ -- for (i = 0; i < sizeof(header); i++) { -- ret = cdns_mhdp_mailbox_read(mhdp); -- if (ret < 0) -- return ret; -- -- header[i] = ret; -- } -- -- mbox_size = get_unaligned_be16(header + 2); -- -- if (opcode != header[0] || module_id != header[1] || -- req_size != mbox_size) { -- /* -- * If the message in mailbox is not what we want, we need to -- * clear the mailbox by reading its contents. -- */ -- for (i = 0; i < mbox_size; i++) -- if (cdns_mhdp_mailbox_read(mhdp) < 0) -- break; -- -- return -EINVAL; -- } -- -- return 0; --} -- --static int cdns_mhdp_mailbox_recv_data(struct cdns_mhdp_device *mhdp, -- u8 *buff, u16 buff_size) --{ -- u32 i; -- int ret; -- -- for (i = 0; i < buff_size; i++) { -- ret = cdns_mhdp_mailbox_read(mhdp); -- if (ret < 0) -- return ret; -- -- buff[i] = ret; -- } -- -- return 0; --} -- --static int cdns_mhdp_mailbox_send(struct cdns_mhdp_device *mhdp, u8 module_id, -- u8 opcode, u16 size, u8 *message) --{ -- u8 header[4]; -- int ret, i; -- -- header[0] = opcode; -- header[1] = module_id; -- put_unaligned_be16(size, header + 2); -- -- for (i = 0; i < sizeof(header); i++) { -- ret = cdns_mhdp_mailbox_write(mhdp, header[i]); -- if (ret) -- return ret; -- } -- -- for (i = 0; i < size; i++) { -- ret = cdns_mhdp_mailbox_write(mhdp, message[i]); -- if (ret) -- return ret; -- } -- -- return 0; --} -- --static --int cdns_mhdp_reg_read(struct cdns_mhdp_device *mhdp, u32 addr, u32 *value) --{ -- u8 msg[4], resp[8]; -- int ret; -- -- put_unaligned_be32(addr, msg); -- -- mutex_lock(&mhdp->mbox_mutex); -- -- ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_GENERAL, -- GENERAL_REGISTER_READ, -- sizeof(msg), msg); -- if (ret) -- goto out; -- -- ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_GENERAL, -- GENERAL_REGISTER_READ, -- sizeof(resp)); -- if (ret) -- goto out; -- -- ret = cdns_mhdp_mailbox_recv_data(mhdp, resp, sizeof(resp)); -- if (ret) -- goto out; -- -- /* Returned address value should be the same as requested */ -- if (memcmp(msg, resp, sizeof(msg))) { -- ret = -EINVAL; -- goto out; -- } -- -- *value = get_unaligned_be32(resp + 4); -- --out: -- mutex_unlock(&mhdp->mbox_mutex); -- if (ret) { -- dev_err(mhdp->dev, "Failed to read register\n"); -- *value = 0; -- } -- -- return ret; --} -- --static --int cdns_mhdp_reg_write(struct cdns_mhdp_device *mhdp, u16 addr, u32 val) --{ -- u8 msg[6]; -- int ret; -- -- put_unaligned_be16(addr, msg); -- put_unaligned_be32(val, msg + 2); -- -- mutex_lock(&mhdp->mbox_mutex); -- -- ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_WRITE_REGISTER, sizeof(msg), msg); -- -- mutex_unlock(&mhdp->mbox_mutex); -- -- return ret; --} -- --static --int cdns_mhdp_reg_write_bit(struct cdns_mhdp_device *mhdp, u16 addr, -- u8 start_bit, u8 bits_no, u32 val) --{ -- u8 field[8]; -- int ret; -- -- put_unaligned_be16(addr, field); -- field[2] = start_bit; -- field[3] = bits_no; -- put_unaligned_be32(val, field + 4); -- -- mutex_lock(&mhdp->mbox_mutex); -- -- ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_WRITE_FIELD, sizeof(field), field); -- -- mutex_unlock(&mhdp->mbox_mutex); -- -- return ret; --} -- --static --int cdns_mhdp_dpcd_read(struct cdns_mhdp_device *mhdp, -- u32 addr, u8 *data, u16 len) --{ -- u8 msg[5], reg[5]; -- int ret; -- -- put_unaligned_be16(len, msg); -- put_unaligned_be24(addr, msg + 2); -- -- mutex_lock(&mhdp->mbox_mutex); -- -- ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_READ_DPCD, sizeof(msg), msg); -- if (ret) -- goto out; -- -- ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_READ_DPCD, -- sizeof(reg) + len); -- if (ret) -- goto out; -- -- ret = cdns_mhdp_mailbox_recv_data(mhdp, reg, sizeof(reg)); -- if (ret) -- goto out; -- -- ret = cdns_mhdp_mailbox_recv_data(mhdp, data, len); -- --out: -- mutex_unlock(&mhdp->mbox_mutex); -- -- return ret; --} -- --static --int cdns_mhdp_dpcd_write(struct cdns_mhdp_device *mhdp, u32 addr, u8 value) --{ -- u8 msg[6], reg[5]; -- int ret; -- -- put_unaligned_be16(1, msg); -- put_unaligned_be24(addr, msg + 2); -- msg[5] = value; -- -- mutex_lock(&mhdp->mbox_mutex); -- -- ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_WRITE_DPCD, sizeof(msg), msg); -- if (ret) -- goto out; -- -- ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_WRITE_DPCD, sizeof(reg)); -- if (ret) -- goto out; -- -- ret = cdns_mhdp_mailbox_recv_data(mhdp, reg, sizeof(reg)); -- if (ret) -- goto out; -- -- if (addr != get_unaligned_be24(reg + 2)) -- ret = -EINVAL; -- --out: -- mutex_unlock(&mhdp->mbox_mutex); -- -- if (ret) -- dev_err(mhdp->dev, "dpcd write failed: %d\n", ret); -- return ret; --} -- - static - int cdns_mhdp_set_firmware_active(struct cdns_mhdp_device *mhdp, bool enable) - { -- u8 msg[5]; -- int ret, i; -- -- msg[0] = GENERAL_MAIN_CONTROL; -- msg[1] = MB_MODULE_ID_GENERAL; -- msg[2] = 0; -- msg[3] = 1; -- msg[4] = enable ? FW_ACTIVE : FW_STANDBY; -- -- mutex_lock(&mhdp->mbox_mutex); -- -- for (i = 0; i < sizeof(msg); i++) { -- ret = cdns_mhdp_mailbox_write(mhdp, msg[i]); -- if (ret) -- goto out; -- } -- -- /* read the firmware state */ -- ret = cdns_mhdp_mailbox_recv_data(mhdp, msg, sizeof(msg)); -- if (ret) -- goto out; -- -- ret = 0; -+ u8 status; -+ int ret; - --out: -- mutex_unlock(&mhdp->mbox_mutex); -+ status = enable ? FW_ACTIVE : FW_STANDBY; - -+ ret = cdns_mhdp_mailbox_send_recv(&mhdp->base, MB_MODULE_ID_GENERAL, -+ GENERAL_MAIN_CONTROL, -+ sizeof(status), &status, -+ sizeof(status), &status); - if (ret < 0) - dev_err(mhdp->dev, "set firmware active failed\n"); - return ret; -@@ -380,34 +96,18 @@ int cdns_mhdp_get_hpd_status(struct cdns_mhdp_device *mhdp) - u8 status; - int ret; - -- mutex_lock(&mhdp->mbox_mutex); -- -- ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_HPD_STATE, 0, NULL); -- if (ret) -- goto err_get_hpd; -- -- ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_HPD_STATE, -- sizeof(status)); -- if (ret) -- goto err_get_hpd; -+ ret = cdns_mhdp_mailbox_send_recv(&mhdp->base, MB_MODULE_ID_DP_TX, -+ DPTX_HPD_STATE, -+ 0, NULL, -+ sizeof(status), &status); - -- ret = cdns_mhdp_mailbox_recv_data(mhdp, &status, sizeof(status)); - if (ret) -- goto err_get_hpd; -- -- mutex_unlock(&mhdp->mbox_mutex); -+ return ret; - - dev_dbg(mhdp->dev, "%s: HPD %splugged\n", __func__, - status ? "" : "un"); - - return status; -- --err_get_hpd: -- mutex_unlock(&mhdp->mbox_mutex); -- -- return ret; - } - - static -@@ -418,28 +118,17 @@ int cdns_mhdp_get_edid_block(void *data, u8 *edid, - u8 msg[2], reg[2], i; - int ret; - -- mutex_lock(&mhdp->mbox_mutex); -- - for (i = 0; i < 4; i++) { - msg[0] = block / 2; - msg[1] = block % 2; - -- ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_GET_EDID, sizeof(msg), msg); -- if (ret) -- continue; -- -- ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_GET_EDID, -- sizeof(reg) + length); -- if (ret) -- continue; -- -- ret = cdns_mhdp_mailbox_recv_data(mhdp, reg, sizeof(reg)); -- if (ret) -- continue; -- -- ret = cdns_mhdp_mailbox_recv_data(mhdp, edid, length); -+ ret = cdns_mhdp_mailbox_send_recv_multi(&mhdp->base, -+ MB_MODULE_ID_DP_TX, -+ DPTX_GET_EDID, -+ sizeof(msg), msg, -+ DPTX_GET_EDID, -+ sizeof(reg), reg, -+ length, edid); - if (ret) - continue; - -@@ -447,8 +136,6 @@ int cdns_mhdp_get_edid_block(void *data, u8 *edid, - break; - } - -- mutex_unlock(&mhdp->mbox_mutex); -- - if (ret) - dev_err(mhdp->dev, "get block[%d] edid failed: %d\n", - block, ret); -@@ -462,21 +149,9 @@ int cdns_mhdp_read_hpd_event(struct cdns_mhdp_device *mhdp) - u8 event = 0; - int ret; - -- mutex_lock(&mhdp->mbox_mutex); -- -- ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_READ_EVENT, 0, NULL); -- if (ret) -- goto out; -- -- ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_READ_EVENT, sizeof(event)); -- if (ret < 0) -- goto out; -- -- ret = cdns_mhdp_mailbox_recv_data(mhdp, &event, sizeof(event)); --out: -- mutex_unlock(&mhdp->mbox_mutex); -+ ret = cdns_mhdp_mailbox_send_recv(&mhdp->base, MB_MODULE_ID_DP_TX, -+ DPTX_READ_EVENT, -+ 0, NULL, sizeof(event), &event); - - if (ret < 0) - return ret; -@@ -510,35 +185,23 @@ int cdns_mhdp_adjust_lt(struct cdns_mhdp_device *mhdp, unsigned int nlanes, - put_unaligned_be16(udelay, payload + 1); - memcpy(payload + 3, lanes_data, nlanes); - -- mutex_lock(&mhdp->mbox_mutex); -- -- ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_ADJUST_LT, -- sizeof(payload), payload); -- if (ret) -- goto out; -- - /* Yes, read the DPCD read command response */ -- ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_READ_DPCD, -- sizeof(hdr) + DP_LINK_STATUS_SIZE); -- if (ret) -- goto out; -- -- ret = cdns_mhdp_mailbox_recv_data(mhdp, hdr, sizeof(hdr)); -+ ret = cdns_mhdp_mailbox_send_recv_multi(&mhdp->base, -+ MB_MODULE_ID_DP_TX, -+ DPTX_ADJUST_LT, -+ sizeof(payload), payload, -+ DPTX_READ_DPCD, -+ sizeof(hdr), hdr, -+ DP_LINK_STATUS_SIZE, -+ link_status); - if (ret) - goto out; - - addr = get_unaligned_be24(hdr + 2); - if (addr != DP_LANE0_1_STATUS) -- goto out; -- -- ret = cdns_mhdp_mailbox_recv_data(mhdp, link_status, -- DP_LINK_STATUS_SIZE); -+ ret = -EINVAL; - - out: -- mutex_unlock(&mhdp->mbox_mutex); -- - if (ret) - dev_err(mhdp->dev, "Failed to adjust Link Training.\n"); - -@@ -847,7 +510,7 @@ static ssize_t cdns_mhdp_transfer(struct drm_dp_aux *aux, - unsigned int i; - - for (i = 0; i < msg->size; ++i) { -- ret = cdns_mhdp_dpcd_write(mhdp, -+ ret = cdns_mhdp_dpcd_write(&mhdp->base, - msg->address + i, buf[i]); - if (!ret) - continue; -@@ -859,7 +522,7 @@ static ssize_t cdns_mhdp_transfer(struct drm_dp_aux *aux, - return ret; - } - } else { -- ret = cdns_mhdp_dpcd_read(mhdp, msg->address, -+ ret = cdns_mhdp_dpcd_read(&mhdp->base, msg->address, - msg->buffer, msg->size); - if (ret) { - dev_err(mhdp->dev, -@@ -887,12 +550,12 @@ static int cdns_mhdp_link_training_init(struct cdns_mhdp_device *mhdp) - if (!mhdp->host.scrambler) - reg32 |= CDNS_PHY_SCRAMBLER_BYPASS; - -- cdns_mhdp_reg_write(mhdp, CDNS_DPTX_PHY_CONFIG, reg32); -+ cdns_mhdp_reg_write(&mhdp->base, CDNS_DPTX_PHY_CONFIG, reg32); - -- cdns_mhdp_reg_write(mhdp, CDNS_DP_ENHNCD, -+ cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_ENHNCD, - mhdp->sink.enhanced & mhdp->host.enhanced); - -- cdns_mhdp_reg_write(mhdp, CDNS_DP_LANE_EN, -+ cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_LANE_EN, - CDNS_DP_LANE_EN_LANES(mhdp->link.num_lanes)); - - cdns_mhdp_link_configure(&mhdp->aux, &mhdp->link); -@@ -913,7 +576,7 @@ static int cdns_mhdp_link_training_init(struct cdns_mhdp_device *mhdp) - return ret; - } - -- cdns_mhdp_reg_write(mhdp, CDNS_DPTX_PHY_CONFIG, -+ cdns_mhdp_reg_write(&mhdp->base, CDNS_DPTX_PHY_CONFIG, - CDNS_PHY_COMMON_CONFIG | - CDNS_PHY_TRAINING_EN | - CDNS_PHY_TRAINING_TYPE(1) | -@@ -1058,7 +721,7 @@ static bool cdns_mhdp_link_training_channel_eq(struct cdns_mhdp_device *mhdp, - CDNS_PHY_TRAINING_TYPE(eq_tps); - if (eq_tps != 4) - reg32 |= CDNS_PHY_SCRAMBLER_BYPASS; -- cdns_mhdp_reg_write(mhdp, CDNS_DPTX_PHY_CONFIG, reg32); -+ cdns_mhdp_reg_write(&mhdp->base, CDNS_DPTX_PHY_CONFIG, reg32); - - drm_dp_dpcd_writeb(&mhdp->aux, DP_TRAINING_PATTERN_SET, - (eq_tps != 4) ? eq_tps | DP_LINK_SCRAMBLING_DISABLE : -@@ -1322,7 +985,7 @@ static int cdns_mhdp_link_training(struct cdns_mhdp_device *mhdp, - mhdp->host.scrambler ? 0 : - DP_LINK_SCRAMBLING_DISABLE); - -- ret = cdns_mhdp_reg_read(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, ®32); -+ ret = cdns_mhdp_reg_read(&mhdp->base, CDNS_DP_FRAMER_GLOBAL_CONFIG, ®32); - if (ret < 0) { - dev_err(mhdp->dev, - "Failed to read CDNS_DP_FRAMER_GLOBAL_CONFIG %d\n", -@@ -1333,13 +996,13 @@ static int cdns_mhdp_link_training(struct cdns_mhdp_device *mhdp, - reg32 |= CDNS_DP_NUM_LANES(mhdp->link.num_lanes); - reg32 |= CDNS_DP_WR_FAILING_EDGE_VSYNC; - reg32 |= CDNS_DP_FRAMER_EN; -- cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, reg32); -+ cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_FRAMER_GLOBAL_CONFIG, reg32); - - /* Reset PHY config */ - reg32 = CDNS_PHY_COMMON_CONFIG | CDNS_PHY_TRAINING_TYPE(1); - if (!mhdp->host.scrambler) - reg32 |= CDNS_PHY_SCRAMBLER_BYPASS; -- cdns_mhdp_reg_write(mhdp, CDNS_DPTX_PHY_CONFIG, reg32); -+ cdns_mhdp_reg_write(&mhdp->base, CDNS_DPTX_PHY_CONFIG, reg32); - - return 0; - err: -@@ -1347,7 +1010,7 @@ static int cdns_mhdp_link_training(struct cdns_mhdp_device *mhdp, - reg32 = CDNS_PHY_COMMON_CONFIG | CDNS_PHY_TRAINING_TYPE(1); - if (!mhdp->host.scrambler) - reg32 |= CDNS_PHY_SCRAMBLER_BYPASS; -- cdns_mhdp_reg_write(mhdp, CDNS_DPTX_PHY_CONFIG, reg32); -+ cdns_mhdp_reg_write(&mhdp->base, CDNS_DPTX_PHY_CONFIG, reg32); - - drm_dp_dpcd_writeb(&mhdp->aux, DP_TRAINING_PATTERN_SET, - DP_TRAINING_PATTERN_DISABLE); -@@ -1461,7 +1124,7 @@ static int cdns_mhdp_link_up(struct cdns_mhdp_device *mhdp) - mhdp->link.num_lanes = cdns_mhdp_max_num_lanes(mhdp); - - /* Disable framer for link training */ -- err = cdns_mhdp_reg_read(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, &resp); -+ err = cdns_mhdp_reg_read(&mhdp->base, CDNS_DP_FRAMER_GLOBAL_CONFIG, &resp); - if (err < 0) { - dev_err(mhdp->dev, - "Failed to read CDNS_DP_FRAMER_GLOBAL_CONFIG %d\n", -@@ -1470,7 +1133,7 @@ static int cdns_mhdp_link_up(struct cdns_mhdp_device *mhdp) - } - - resp &= ~CDNS_DP_FRAMER_EN; -- cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, resp); -+ cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_FRAMER_GLOBAL_CONFIG, resp); - - /* Spread AMP if required, enable 8b/10b coding */ - amp[0] = cdns_mhdp_get_ssc_supported(mhdp) ? DP_SPREAD_AMP_0_5 : 0; -@@ -1834,7 +1497,7 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp, - if (mode->flags & DRM_MODE_FLAG_INTERLACE) - bnd_hsync2vsync |= CDNS_IP_DET_INTERLACE_FORMAT; - -- cdns_mhdp_reg_write(mhdp, CDNS_BND_HSYNC2VSYNC(stream_id), -+ cdns_mhdp_reg_write(&mhdp->base, CDNS_BND_HSYNC2VSYNC(stream_id), - bnd_hsync2vsync); - - hsync2vsync_pol_ctrl = 0; -@@ -1842,10 +1505,10 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp, - hsync2vsync_pol_ctrl |= CDNS_H2V_HSYNC_POL_ACTIVE_LOW; - if (mode->flags & DRM_MODE_FLAG_NVSYNC) - hsync2vsync_pol_ctrl |= CDNS_H2V_VSYNC_POL_ACTIVE_LOW; -- cdns_mhdp_reg_write(mhdp, CDNS_HSYNC2VSYNC_POL_CTRL(stream_id), -+ cdns_mhdp_reg_write(&mhdp->base, CDNS_HSYNC2VSYNC_POL_CTRL(stream_id), - hsync2vsync_pol_ctrl); - -- cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_PXL_REPR(stream_id), pxl_repr); -+ cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_FRAMER_PXL_REPR(stream_id), pxl_repr); - - if (mode->flags & DRM_MODE_FLAG_INTERLACE) - dp_framer_sp |= CDNS_DP_FRAMER_INTERLACE; -@@ -1853,19 +1516,19 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp, - dp_framer_sp |= CDNS_DP_FRAMER_HSYNC_POL_LOW; - if (mode->flags & DRM_MODE_FLAG_NVSYNC) - dp_framer_sp |= CDNS_DP_FRAMER_VSYNC_POL_LOW; -- cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_SP(stream_id), dp_framer_sp); -+ cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_FRAMER_SP(stream_id), dp_framer_sp); - - front_porch = mode->crtc_hsync_start - mode->crtc_hdisplay; - back_porch = mode->crtc_htotal - mode->crtc_hsync_end; -- cdns_mhdp_reg_write(mhdp, CDNS_DP_FRONT_BACK_PORCH(stream_id), -+ cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_FRONT_BACK_PORCH(stream_id), - CDNS_DP_FRONT_PORCH(front_porch) | - CDNS_DP_BACK_PORCH(back_porch)); - -- cdns_mhdp_reg_write(mhdp, CDNS_DP_BYTE_COUNT(stream_id), -+ cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_BYTE_COUNT(stream_id), - mode->crtc_hdisplay * bpp / 8); - - msa_h0 = mode->crtc_htotal - mode->crtc_hsync_start; -- cdns_mhdp_reg_write(mhdp, CDNS_DP_MSA_HORIZONTAL_0(stream_id), -+ cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_MSA_HORIZONTAL_0(stream_id), - CDNS_DP_MSAH0_H_TOTAL(mode->crtc_htotal) | - CDNS_DP_MSAH0_HSYNC_START(msa_h0)); - -@@ -1874,11 +1537,11 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp, - CDNS_DP_MSAH1_HDISP_WIDTH(mode->crtc_hdisplay); - if (mode->flags & DRM_MODE_FLAG_NHSYNC) - msa_horizontal_1 |= CDNS_DP_MSAH1_HSYNC_POL_LOW; -- cdns_mhdp_reg_write(mhdp, CDNS_DP_MSA_HORIZONTAL_1(stream_id), -+ cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_MSA_HORIZONTAL_1(stream_id), - msa_horizontal_1); - - msa_v0 = mode->crtc_vtotal - mode->crtc_vsync_start; -- cdns_mhdp_reg_write(mhdp, CDNS_DP_MSA_VERTICAL_0(stream_id), -+ cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_MSA_VERTICAL_0(stream_id), - CDNS_DP_MSAV0_V_TOTAL(mode->crtc_vtotal) | - CDNS_DP_MSAV0_VSYNC_START(msa_v0)); - -@@ -1887,7 +1550,7 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp, - CDNS_DP_MSAV1_VDISP_WIDTH(mode->crtc_vdisplay); - if (mode->flags & DRM_MODE_FLAG_NVSYNC) - msa_vertical_1 |= CDNS_DP_MSAV1_VSYNC_POL_LOW; -- cdns_mhdp_reg_write(mhdp, CDNS_DP_MSA_VERTICAL_1(stream_id), -+ cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_MSA_VERTICAL_1(stream_id), - msa_vertical_1); - - if ((mode->flags & DRM_MODE_FLAG_INTERLACE) && -@@ -1899,14 +1562,14 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp, - if (pxlfmt == DRM_COLOR_FORMAT_YCBCR420) - misc1 = CDNS_DP_TEST_VSC_SDP; - -- cdns_mhdp_reg_write(mhdp, CDNS_DP_MSA_MISC(stream_id), -+ cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_MSA_MISC(stream_id), - misc0 | (misc1 << 8)); - -- cdns_mhdp_reg_write(mhdp, CDNS_DP_HORIZONTAL(stream_id), -+ cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_HORIZONTAL(stream_id), - CDNS_DP_H_HSYNC_WIDTH(hsync) | - CDNS_DP_H_H_TOTAL(mode->crtc_hdisplay)); - -- cdns_mhdp_reg_write(mhdp, CDNS_DP_VERTICAL_0(stream_id), -+ cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_VERTICAL_0(stream_id), - CDNS_DP_V0_VHEIGHT(mode->crtc_vdisplay) | - CDNS_DP_V0_VSTART(msa_v0)); - -@@ -1915,13 +1578,13 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp, - mode->crtc_vtotal % 2 == 0) - dp_vertical_1 |= CDNS_DP_V1_VTOTAL_EVEN; - -- cdns_mhdp_reg_write(mhdp, CDNS_DP_VERTICAL_1(stream_id), dp_vertical_1); -+ cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_VERTICAL_1(stream_id), dp_vertical_1); - -- cdns_mhdp_reg_write_bit(mhdp, CDNS_DP_VB_ID(stream_id), 2, 1, -- (mode->flags & DRM_MODE_FLAG_INTERLACE) ? -- CDNS_DP_VB_ID_INTERLACED : 0); -+ cdns_mhdp_dp_reg_write_bit(&mhdp->base, CDNS_DP_VB_ID(stream_id), 2, 1, -+ (mode->flags & DRM_MODE_FLAG_INTERLACE) ? -+ CDNS_DP_VB_ID_INTERLACED : 0); - -- ret = cdns_mhdp_reg_read(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, &framer); -+ ret = cdns_mhdp_reg_read(&mhdp->base, CDNS_DP_FRAMER_GLOBAL_CONFIG, &framer); - if (ret < 0) { - dev_err(mhdp->dev, - "Failed to read CDNS_DP_FRAMER_GLOBAL_CONFIG %d\n", -@@ -1930,7 +1593,7 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp, - } - framer |= CDNS_DP_FRAMER_EN; - framer &= ~CDNS_DP_NO_VIDEO_MODE; -- cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, framer); -+ cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_FRAMER_GLOBAL_CONFIG, framer); - } - - static void cdns_mhdp_sst_enable(struct cdns_mhdp_device *mhdp, -@@ -1963,15 +1626,15 @@ static void cdns_mhdp_sst_enable(struct cdns_mhdp_device *mhdp, - - mhdp->stream_id = 0; - -- cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_TU, -+ cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_FRAMER_TU, - CDNS_DP_FRAMER_TU_VS(vs) | - CDNS_DP_FRAMER_TU_SIZE(tu_size) | - CDNS_DP_FRAMER_TU_CNT_RST_EN); - -- cdns_mhdp_reg_write(mhdp, CDNS_DP_LINE_THRESH(0), -+ cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_LINE_THRESH(0), - line_thresh & GENMASK(5, 0)); - -- cdns_mhdp_reg_write(mhdp, CDNS_DP_STREAM_CONFIG_2(0), -+ cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_STREAM_CONFIG_2(0), - CDNS_DP_SC2_TU_VS_DIFF((tu_size - vs > 3) ? - 0 : tu_size - vs)); - -@@ -2006,13 +1669,13 @@ static void cdns_mhdp_atomic_enable(struct drm_bridge *bridge, - mhdp->info->ops->enable(mhdp); - - /* Enable VIF clock for stream 0 */ -- ret = cdns_mhdp_reg_read(mhdp, CDNS_DPTX_CAR, &resp); -+ ret = cdns_mhdp_reg_read(&mhdp->base, CDNS_DPTX_CAR, &resp); - if (ret < 0) { - dev_err(mhdp->dev, "Failed to read CDNS_DPTX_CAR %d\n", ret); - goto out; - } - -- cdns_mhdp_reg_write(mhdp, CDNS_DPTX_CAR, -+ cdns_mhdp_reg_write(&mhdp->base, CDNS_DPTX_CAR, - resp | CDNS_VIF_CLK_EN | CDNS_VIF_CLK_RSTN); - - connector = drm_atomic_get_new_connector_for_encoder(state, -@@ -2083,16 +1746,16 @@ static void cdns_mhdp_atomic_disable(struct drm_bridge *bridge, - cdns_mhdp_hdcp_disable(mhdp); - - mhdp->bridge_enabled = false; -- cdns_mhdp_reg_read(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, &resp); -+ cdns_mhdp_reg_read(&mhdp->base, CDNS_DP_FRAMER_GLOBAL_CONFIG, &resp); - resp &= ~CDNS_DP_FRAMER_EN; - resp |= CDNS_DP_NO_VIDEO_MODE; -- cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, resp); -+ cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_FRAMER_GLOBAL_CONFIG, resp); - - cdns_mhdp_link_down(mhdp); - - /* Disable VIF clock for stream 0 */ -- cdns_mhdp_reg_read(mhdp, CDNS_DPTX_CAR, &resp); -- cdns_mhdp_reg_write(mhdp, CDNS_DPTX_CAR, -+ cdns_mhdp_reg_read(&mhdp->base, CDNS_DPTX_CAR, &resp); -+ cdns_mhdp_reg_write(&mhdp->base, CDNS_DPTX_CAR, - resp & ~(CDNS_VIF_CLK_EN | CDNS_VIF_CLK_RSTN)); - - if (mhdp->info && mhdp->info->ops && mhdp->info->ops->disable) -@@ -2471,7 +2134,6 @@ static int cdns_mhdp_probe(struct platform_device *pdev) - - mhdp->clk = clk; - mhdp->dev = dev; -- mutex_init(&mhdp->mbox_mutex); - mutex_init(&mhdp->link_mutex); - spin_lock_init(&mhdp->start_lock); - -@@ -2502,6 +2164,11 @@ static int cdns_mhdp_probe(struct platform_device *pdev) - - platform_set_drvdata(pdev, mhdp); - -+ /* init base struct for access mailbox */ -+ mhdp->base.dev = mhdp->dev; -+ mhdp->base.regs = mhdp->regs; -+ mhdp->base.sapb_regs = mhdp->sapb_regs; -+ - mhdp->info = of_device_get_match_data(dev); - - clk_prepare_enable(clk); -diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h -index bad2fc0c73066..d209c7b3bbfab 100644 ---- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h -+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h -@@ -15,6 +15,7 @@ - #include <linux/mutex.h> - #include <linux/spinlock.h> - -+#include <drm/bridge/cdns-mhdp-helper.h> - #include <drm/display/drm_dp_helper.h> - #include <drm/drm_bridge.h> - #include <drm/drm_connector.h> -@@ -27,10 +28,6 @@ struct phy; - #define CDNS_APB_CTRL 0x00000 - #define CDNS_CPU_STALL BIT(3) - --#define CDNS_MAILBOX_FULL 0x00008 --#define CDNS_MAILBOX_EMPTY 0x0000c --#define CDNS_MAILBOX_TX_DATA 0x00010 --#define CDNS_MAILBOX_RX_DATA 0x00014 - #define CDNS_KEEP_ALIVE 0x00018 - #define CDNS_KEEP_ALIVE_MASK GENMASK(7, 0) - -@@ -198,45 +195,10 @@ struct phy; - #define CDNS_DP_BYTE_COUNT(s) (CDNS_DPTX_STREAM(s) + 0x7c) - #define CDNS_DP_BYTE_COUNT_BYTES_IN_CHUNK_SHIFT 16 - --/* mailbox */ --#define MAILBOX_RETRY_US 1000 --#define MAILBOX_TIMEOUT_US 2000000 -- --#define MB_OPCODE_ID 0 --#define MB_MODULE_ID 1 --#define MB_SIZE_MSB_ID 2 --#define MB_SIZE_LSB_ID 3 --#define MB_DATA_ID 4 -- --#define MB_MODULE_ID_DP_TX 0x01 --#define MB_MODULE_ID_HDCP_TX 0x07 --#define MB_MODULE_ID_HDCP_RX 0x08 --#define MB_MODULE_ID_HDCP_GENERAL 0x09 --#define MB_MODULE_ID_GENERAL 0x0a -- --/* firmware and opcodes */ -+/* firmware */ - #define FW_NAME "cadence/mhdp8546.bin" - #define CDNS_MHDP_IMEM 0x10000 - --#define GENERAL_MAIN_CONTROL 0x01 --#define GENERAL_TEST_ECHO 0x02 --#define GENERAL_BUS_SETTINGS 0x03 --#define GENERAL_TEST_ACCESS 0x04 --#define GENERAL_REGISTER_READ 0x07 -- --#define DPTX_SET_POWER_MNG 0x00 --#define DPTX_GET_EDID 0x02 --#define DPTX_READ_DPCD 0x03 --#define DPTX_WRITE_DPCD 0x04 --#define DPTX_ENABLE_EVENT 0x05 --#define DPTX_WRITE_REGISTER 0x06 --#define DPTX_READ_REGISTER 0x07 --#define DPTX_WRITE_FIELD 0x08 --#define DPTX_READ_EVENT 0x0a --#define DPTX_GET_LAST_AUX_STAUS 0x0e --#define DPTX_HPD_STATE 0x11 --#define DPTX_ADJUST_LT 0x12 -- - #define FW_STANDBY 0 - #define FW_ACTIVE 1 - -@@ -352,6 +314,8 @@ struct cdns_mhdp_hdcp { - }; - - struct cdns_mhdp_device { -+ struct cdns_mhdp_base base; -+ - void __iomem *regs; - void __iomem *sapb_regs; - void __iomem *j721e_regs; -@@ -362,9 +326,6 @@ struct cdns_mhdp_device { - - const struct cdns_mhdp_platform_info *info; - -- /* This is to protect mailbox communications with the firmware */ -- struct mutex mbox_mutex; -- - /* - * "link_mutex" protects the access to all the link parameters - * including the link training process. Link training will be -diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c -index 31832ba4017f1..0d3979577a924 100644 ---- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c -@@ -15,144 +15,20 @@ - - #include "cdns-mhdp8546-hdcp.h" - --static int cdns_mhdp_secure_mailbox_read(struct cdns_mhdp_device *mhdp) --{ -- int ret, empty; -- -- WARN_ON(!mutex_is_locked(&mhdp->mbox_mutex)); -- -- ret = readx_poll_timeout(readl, mhdp->sapb_regs + CDNS_MAILBOX_EMPTY, -- empty, !empty, MAILBOX_RETRY_US, -- MAILBOX_TIMEOUT_US); -- if (ret < 0) -- return ret; -- -- return readl(mhdp->sapb_regs + CDNS_MAILBOX_RX_DATA) & 0xff; --} -- --static int cdns_mhdp_secure_mailbox_write(struct cdns_mhdp_device *mhdp, -- u8 val) --{ -- int ret, full; -- -- WARN_ON(!mutex_is_locked(&mhdp->mbox_mutex)); -- -- ret = readx_poll_timeout(readl, mhdp->sapb_regs + CDNS_MAILBOX_FULL, -- full, !full, MAILBOX_RETRY_US, -- MAILBOX_TIMEOUT_US); -- if (ret < 0) -- return ret; -- -- writel(val, mhdp->sapb_regs + CDNS_MAILBOX_TX_DATA); -- -- return 0; --} -- --static int cdns_mhdp_secure_mailbox_recv_header(struct cdns_mhdp_device *mhdp, -- u8 module_id, -- u8 opcode, -- u16 req_size) --{ -- u32 mbox_size, i; -- u8 header[4]; -- int ret; -- -- /* read the header of the message */ -- for (i = 0; i < sizeof(header); i++) { -- ret = cdns_mhdp_secure_mailbox_read(mhdp); -- if (ret < 0) -- return ret; -- -- header[i] = ret; -- } -- -- mbox_size = get_unaligned_be16(header + 2); -- -- if (opcode != header[0] || module_id != header[1] || -- (opcode != HDCP_TRAN_IS_REC_ID_VALID && req_size != mbox_size)) { -- for (i = 0; i < mbox_size; i++) -- if (cdns_mhdp_secure_mailbox_read(mhdp) < 0) -- break; -- return -EINVAL; -- } -- -- return 0; --} -- --static int cdns_mhdp_secure_mailbox_recv_data(struct cdns_mhdp_device *mhdp, -- u8 *buff, u16 buff_size) --{ -- int ret; -- u32 i; -- -- for (i = 0; i < buff_size; i++) { -- ret = cdns_mhdp_secure_mailbox_read(mhdp); -- if (ret < 0) -- return ret; -- -- buff[i] = ret; -- } -- -- return 0; --} -- --static int cdns_mhdp_secure_mailbox_send(struct cdns_mhdp_device *mhdp, -- u8 module_id, -- u8 opcode, -- u16 size, -- u8 *message) --{ -- u8 header[4]; -- int ret; -- u32 i; -- -- header[0] = opcode; -- header[1] = module_id; -- put_unaligned_be16(size, header + 2); -- -- for (i = 0; i < sizeof(header); i++) { -- ret = cdns_mhdp_secure_mailbox_write(mhdp, header[i]); -- if (ret) -- return ret; -- } -- -- for (i = 0; i < size; i++) { -- ret = cdns_mhdp_secure_mailbox_write(mhdp, message[i]); -- if (ret) -- return ret; -- } -- -- return 0; --} -- - static int cdns_mhdp_hdcp_get_status(struct cdns_mhdp_device *mhdp, - u16 *hdcp_port_status) - { - u8 hdcp_status[HDCP_STATUS_SIZE]; - int ret; - -- mutex_lock(&mhdp->mbox_mutex); -- ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_TX, -- HDCP_TRAN_STATUS_CHANGE, 0, NULL); -- if (ret) -- goto err_get_hdcp_status; -- -- ret = cdns_mhdp_secure_mailbox_recv_header(mhdp, MB_MODULE_ID_HDCP_TX, -- HDCP_TRAN_STATUS_CHANGE, -- sizeof(hdcp_status)); -- if (ret) -- goto err_get_hdcp_status; -- -- ret = cdns_mhdp_secure_mailbox_recv_data(mhdp, hdcp_status, -- sizeof(hdcp_status)); -+ ret = cdns_mhdp_secure_mailbox_send_recv(&mhdp->base, MB_MODULE_ID_HDCP_TX, -+ HDCP_TRAN_STATUS_CHANGE, 0, NULL, -+ sizeof(hdcp_status), hdcp_status); - if (ret) -- goto err_get_hdcp_status; -+ return ret; - - *hdcp_port_status = ((u16)(hdcp_status[0] << 8) | hdcp_status[1]); - --err_get_hdcp_status: -- mutex_unlock(&mhdp->mbox_mutex); -- - return ret; - } - -@@ -170,98 +46,52 @@ static u8 cdns_mhdp_hdcp_handle_status(struct cdns_mhdp_device *mhdp, - static int cdns_mhdp_hdcp_rx_id_valid_response(struct cdns_mhdp_device *mhdp, - u8 valid) - { -- int ret; -- -- mutex_lock(&mhdp->mbox_mutex); -- ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_TX, -+ return cdns_mhdp_secure_mailbox_send(&mhdp->base, MB_MODULE_ID_HDCP_TX, - HDCP_TRAN_RESPOND_RECEIVER_ID_VALID, - 1, &valid); -- mutex_unlock(&mhdp->mbox_mutex); -- -- return ret; - } - - static int cdns_mhdp_hdcp_rx_id_valid(struct cdns_mhdp_device *mhdp, - u8 *recv_num, u8 *hdcp_rx_id) - { - u8 rec_id_hdr[2]; -- u8 status; - int ret; - -- mutex_lock(&mhdp->mbox_mutex); -- ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_TX, -- HDCP_TRAN_IS_REC_ID_VALID, 0, NULL); -- if (ret) -- goto err_rx_id_valid; -- -- ret = cdns_mhdp_secure_mailbox_recv_header(mhdp, MB_MODULE_ID_HDCP_TX, -- HDCP_TRAN_IS_REC_ID_VALID, -- sizeof(status)); -+ ret = cdns_mhdp_secure_mailbox_send_recv_multi(&mhdp->base, -+ MB_MODULE_ID_HDCP_TX, -+ HDCP_TRAN_IS_REC_ID_VALID, -+ 0, NULL, -+ HDCP_TRAN_IS_REC_ID_VALID, -+ sizeof(rec_id_hdr), rec_id_hdr, -+ 0, hdcp_rx_id); - if (ret) -- goto err_rx_id_valid; -- -- ret = cdns_mhdp_secure_mailbox_recv_data(mhdp, rec_id_hdr, 2); -- if (ret) -- goto err_rx_id_valid; -+ return ret; - - *recv_num = rec_id_hdr[0]; - -- ret = cdns_mhdp_secure_mailbox_recv_data(mhdp, hdcp_rx_id, 5 * *recv_num); -- --err_rx_id_valid: -- mutex_unlock(&mhdp->mbox_mutex); -- -- return ret; -+ return 0; - } - - static int cdns_mhdp_hdcp_km_stored_resp(struct cdns_mhdp_device *mhdp, - u32 size, u8 *km) - { -- int ret; -- -- mutex_lock(&mhdp->mbox_mutex); -- ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_TX, -- HDCP2X_TX_RESPOND_KM, size, km); -- mutex_unlock(&mhdp->mbox_mutex); -- -- return ret; -+ return cdns_mhdp_secure_mailbox_send(&mhdp->base, MB_MODULE_ID_HDCP_TX, -+ HDCP2X_TX_RESPOND_KM, size, km); - } - - static int cdns_mhdp_hdcp_tx_is_km_stored(struct cdns_mhdp_device *mhdp, - u8 *resp, u32 size) - { -- int ret; -- -- mutex_lock(&mhdp->mbox_mutex); -- ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_TX, -- HDCP2X_TX_IS_KM_STORED, 0, NULL); -- if (ret) -- goto err_is_km_stored; -- -- ret = cdns_mhdp_secure_mailbox_recv_header(mhdp, MB_MODULE_ID_HDCP_TX, -- HDCP2X_TX_IS_KM_STORED, -- size); -- if (ret) -- goto err_is_km_stored; -- -- ret = cdns_mhdp_secure_mailbox_recv_data(mhdp, resp, size); --err_is_km_stored: -- mutex_unlock(&mhdp->mbox_mutex); -- -- return ret; -+ return cdns_mhdp_secure_mailbox_send_recv(&mhdp->base, MB_MODULE_ID_HDCP_TX, -+ HDCP2X_TX_IS_KM_STORED, -+ 0, NULL, size, resp); - } - - static int cdns_mhdp_hdcp_tx_config(struct cdns_mhdp_device *mhdp, - u8 hdcp_cfg) - { -- int ret; -- -- mutex_lock(&mhdp->mbox_mutex); -- ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_TX, -- HDCP_TRAN_CONFIGURATION, 1, &hdcp_cfg); -- mutex_unlock(&mhdp->mbox_mutex); -- -- return ret; -+ return cdns_mhdp_secure_mailbox_send(&mhdp->base, MB_MODULE_ID_HDCP_TX, -+ HDCP_TRAN_CONFIGURATION, 1, &hdcp_cfg); - } - - static int cdns_mhdp_hdcp_set_config(struct cdns_mhdp_device *mhdp, -@@ -502,30 +332,18 @@ static void cdns_mhdp_hdcp_prop_work(struct work_struct *work) - - int cdns_mhdp_hdcp_set_lc(struct cdns_mhdp_device *mhdp, u8 *val) - { -- int ret; -- -- mutex_lock(&mhdp->mbox_mutex); -- ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_GENERAL, -- HDCP_GENERAL_SET_LC_128, -- 16, val); -- mutex_unlock(&mhdp->mbox_mutex); -- -- return ret; -+ return cdns_mhdp_secure_mailbox_send(&mhdp->base, MB_MODULE_ID_HDCP_GENERAL, -+ HDCP_GENERAL_SET_LC_128, -+ 16, val); - } - - int - cdns_mhdp_hdcp_set_public_key_param(struct cdns_mhdp_device *mhdp, - struct cdns_hdcp_tx_public_key_param *val) - { -- int ret; -- -- mutex_lock(&mhdp->mbox_mutex); -- ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_TX, -- HDCP2X_TX_SET_PUBLIC_KEY_PARAMS, -- sizeof(*val), (u8 *)val); -- mutex_unlock(&mhdp->mbox_mutex); -- -- return ret; -+ return cdns_mhdp_secure_mailbox_send(&mhdp->base, MB_MODULE_ID_HDCP_TX, -+ HDCP2X_TX_SET_PUBLIC_KEY_PARAMS, -+ sizeof(*val), (u8 *)val); - } - - int cdns_mhdp_hdcp_enable(struct cdns_mhdp_device *mhdp, u8 content_type) -diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.h b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.h -index 334c0b8b0d4f5..fff4194c7dfd0 100644 ---- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.h -+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.h -@@ -9,6 +9,7 @@ - #ifndef CDNS_MHDP8546_HDCP_H - #define CDNS_MHDP8546_HDCP_H - -+#include <drm/bridge/cdns-mhdp-helper.h> - #include "cdns-mhdp8546-core.h" - - #define HDCP_MAX_RECEIVERS 32 -@@ -32,23 +33,6 @@ enum { - HDCP_SET_SEED, - }; - --enum { -- HDCP_TRAN_CONFIGURATION, -- HDCP2X_TX_SET_PUBLIC_KEY_PARAMS, -- HDCP2X_TX_SET_DEBUG_RANDOM_NUMBERS, -- HDCP2X_TX_RESPOND_KM, -- HDCP1_TX_SEND_KEYS, -- HDCP1_TX_SEND_RANDOM_AN, -- HDCP_TRAN_STATUS_CHANGE, -- HDCP2X_TX_IS_KM_STORED, -- HDCP2X_TX_STORE_KM, -- HDCP_TRAN_IS_REC_ID_VALID, -- HDCP_TRAN_RESPOND_RECEIVER_ID_VALID, -- HDCP_TRAN_TEST_KEYS, -- HDCP2X_TX_SET_KM_KEY_PARAMS, -- HDCP_NUM_OF_SUPPORTED_MESSAGES --}; -- - enum { - HDCP_CONTENT_TYPE_0, - HDCP_CONTENT_TYPE_1, -diff --git a/include/drm/bridge/cdns-mhdp-helper.h b/include/drm/bridge/cdns-mhdp-helper.h -new file mode 100644 -index 0000000000000..25b9737de615f ---- /dev/null -+++ b/include/drm/bridge/cdns-mhdp-helper.h -@@ -0,0 +1,129 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * Copyright (C) 2023-2024 NXP Semiconductor, Inc. -+ */ -+#ifndef __CDNS_MHDP_HELPER_H__ -+#define __CDNS_MHDP_HELPER_H__ -+ -+#include <linux/iopoll.h> -+#include <linux/unaligned.h> -+ -+/* mailbox regs offset */ -+#define CDNS_MAILBOX_FULL 0x00008 -+#define CDNS_MAILBOX_EMPTY 0x0000c -+#define CDNS_MAILBOX_TX_DATA 0x00010 -+#define CDNS_MAILBOX_RX_DATA 0x00014 -+ -+#define MAILBOX_RETRY_US 1000 -+#define MAILBOX_TIMEOUT_US 2000000 -+ -+/* Module ID Code */ -+#define MB_MODULE_ID_DP_TX 0x01 -+#define MB_MODULE_ID_HDMI_TX 0x03 -+#define MB_MODULE_ID_HDCP_TX 0x07 -+#define MB_MODULE_ID_HDCP_RX 0x08 -+#define MB_MODULE_ID_HDCP_GENERAL 0x09 -+#define MB_MODULE_ID_GENERAL 0x0A -+ -+/* General Commands */ -+#define GENERAL_MAIN_CONTROL 0x01 -+#define GENERAL_TEST_ECHO 0x02 -+#define GENERAL_BUS_SETTINGS 0x03 -+#define GENERAL_TEST_ACCESS 0x04 -+#define GENERAL_REGISTER_WRITE 0x05 -+#define GENERAL_WRITE_FIELD 0x06 -+#define GENERAL_REGISTER_READ 0x07 -+#define GENERAL_GET_HPD_STATE 0x11 -+ -+/* DPTX Commands */ -+#define DPTX_SET_POWER_MNG 0x00 -+#define DPTX_SET_HOST_CAPABILITIES 0x01 -+#define DPTX_GET_EDID 0x02 -+#define DPTX_READ_DPCD 0x03 -+#define DPTX_WRITE_DPCD 0x04 -+#define DPTX_ENABLE_EVENT 0x05 -+#define DPTX_WRITE_REGISTER 0x06 -+#define DPTX_READ_REGISTER 0x07 -+#define DPTX_WRITE_FIELD 0x08 -+#define DPTX_TRAINING_CONTROL 0x09 -+#define DPTX_READ_EVENT 0x0a -+#define DPTX_READ_LINK_STAT 0x0b -+#define DPTX_SET_VIDEO 0x0c -+#define DPTX_SET_AUDIO 0x0d -+#define DPTX_GET_LAST_AUX_STAUS 0x0e -+#define DPTX_SET_LINK_BREAK_POINT 0x0f -+#define DPTX_FORCE_LANES 0x10 -+#define DPTX_HPD_STATE 0x11 -+#define DPTX_ADJUST_LT 0x12 -+ -+/* HDMI TX Commands */ -+#define HDMI_TX_READ 0x00 -+#define HDMI_TX_WRITE 0x01 -+#define HDMI_TX_UPDATE_READ 0x02 -+#define HDMI_TX_EDID 0x03 -+#define HDMI_TX_EVENTS 0x04 -+#define HDMI_TX_HPD_STATUS 0x05 -+ -+/* HDCP TX Commands */ -+#define HDCP_TRAN_CONFIGURATION 0x00 -+#define HDCP2X_TX_SET_PUBLIC_KEY_PARAMS 0x01 -+#define HDCP2X_TX_SET_DEBUG_RANDOM_NUMBERS 0x02 -+#define HDCP2X_TX_RESPOND_KM 0x03 -+#define HDCP1_TX_SEND_KEYS 0x04 -+#define HDCP1_TX_SEND_RANDOM_AN 0x05 -+#define HDCP_TRAN_STATUS_CHANGE 0x06 -+#define HDCP2X_TX_IS_KM_STORED 0x07 -+#define HDCP2X_TX_STORE_KM 0x08 -+#define HDCP_TRAN_IS_REC_ID_VALID 0x09 -+#define HDCP_TRAN_RESPOND_RECEIVER_ID_VALID 0x09 -+#define HDCP_TRAN_TEST_KEYS 0x0a -+#define HDCP2X_TX_SET_KM_KEY_PARAMS 0x0b -+#define HDCP_NUM_OF_SUPPORTED_MESSAGES 0x0c -+ -+struct cdns_mhdp_base { -+ struct device *dev; -+ void __iomem *regs; -+ void __iomem *sapb_regs; -+}; -+ -+/* Mailbox helper functions */ -+int cdns_mhdp_mailbox_send(struct cdns_mhdp_base *base, -+ u8 module_id, u8 opcode, -+ u16 size, u8 *message); -+int cdns_mhdp_mailbox_send_recv(struct cdns_mhdp_base *base, -+ u8 module_id, u8 opcode, -+ u16 msg_size, u8 *msg, -+ u16 resp_size, u8 *resp); -+int cdns_mhdp_mailbox_send_recv_multi(struct cdns_mhdp_base *base, -+ u8 module_id, u8 opcode, -+ u16 msg_size, u8 *msg, -+ u8 opcode_resp, -+ u16 resp1_size, u8 *resp1, -+ u16 resp2_size, u8 *resp2); -+ -+/* Secure mailbox helper functions */ -+int cdns_mhdp_secure_mailbox_send(struct cdns_mhdp_base *base, -+ u8 module_id, u8 opcode, -+ u16 size, u8 *message); -+int cdns_mhdp_secure_mailbox_send_recv(struct cdns_mhdp_base *base, -+ u8 module_id, u8 opcode, -+ u16 msg_size, u8 *msg, -+ u16 resp_size, u8 *resp); -+int cdns_mhdp_secure_mailbox_send_recv_multi(struct cdns_mhdp_base *base, -+ u8 module_id, u8 opcode, -+ u16 msg_size, u8 *msg, -+ u8 opcode_resp, -+ u16 resp1_size, u8 *resp1, -+ u16 resp2_size, u8 *resp2); -+ -+/* General commands helper functions */ -+int cdns_mhdp_reg_read(struct cdns_mhdp_base *base, u32 addr, u32 *value); -+int cdns_mhdp_reg_write(struct cdns_mhdp_base *base, u32 addr, u32 val); -+ -+/* DPTX commands helper functions */ -+int cdns_mhdp_dp_reg_write_bit(struct cdns_mhdp_base *base, u16 addr, -+ u8 start_bit, u8 bits_no, u32 val); -+int cdns_mhdp_dpcd_read(struct cdns_mhdp_base *base, -+ u32 addr, u8 *data, u16 len); -+int cdns_mhdp_dpcd_write(struct cdns_mhdp_base *base, u32 addr, u8 value); -+#endif /* __CDNS_MHDP_HELPER_H__ */ --- -2.34.1 - -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH v19 2/8] phy: Add HDMI configuration options -From: Sandor Yu <Sandor.yu@nxp.com> -Date: Tue, 26 Nov 2024 22:11:47 +0800 -Message-Id: <43757beec6cd418fc17252283de38009d531c7c7.1732627815.git.Sandor.yu@nxp.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -Allow HDMI PHYs to be configured through the generic -functions through a custom structure added to the generic union. - -The parameters added here are based on HDMI PHY -implementation practices. The current set of parameters -should cover the potential users. - -Signed-off-by: Sandor Yu <Sandor.yu@nxp.com> -Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> -Reviewed-by: Maxime Ripard <mripard@kernel.org> ---- -v17->v19: - *No change. - -v16->v17: -- remove headfile hdmi.h -- add 2024 year to copyright -- Add r-b tag. - - include/linux/phy/phy-hdmi.h | 19 +++++++++++++++++++ - include/linux/phy/phy.h | 7 ++++++- - 2 files changed, 25 insertions(+), 1 deletion(-) - create mode 100644 include/linux/phy/phy-hdmi.h - -diff --git a/include/linux/phy/phy-hdmi.h b/include/linux/phy/phy-hdmi.h -new file mode 100644 -index 0000000000000..6a696922bc7f2 ---- /dev/null -+++ b/include/linux/phy/phy-hdmi.h -@@ -0,0 +1,19 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright 2022,2024 NXP -+ */ -+ -+#ifndef __PHY_HDMI_H_ -+#define __PHY_HDMI_H_ -+ -+/** -+ * struct phy_configure_opts_hdmi - HDMI configuration set -+ * @tmds_char_rate: HDMI TMDS Character Rate in Hertz. -+ * -+ * This structure is used to represent the configuration state of a HDMI phy. -+ */ -+struct phy_configure_opts_hdmi { -+ unsigned long long tmds_char_rate; -+}; -+ -+#endif /* __PHY_HDMI_H_ */ -diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h -index 03cd5bae92d3f..4ac486b101fe4 100644 ---- a/include/linux/phy/phy.h -+++ b/include/linux/phy/phy.h -@@ -17,6 +17,7 @@ - #include <linux/regulator/consumer.h> - - #include <linux/phy/phy-dp.h> -+#include <linux/phy/phy-hdmi.h> - #include <linux/phy/phy-lvds.h> - #include <linux/phy/phy-mipi-dphy.h> - -@@ -42,7 +43,8 @@ enum phy_mode { - PHY_MODE_MIPI_DPHY, - PHY_MODE_SATA, - PHY_MODE_LVDS, -- PHY_MODE_DP -+ PHY_MODE_DP, -+ PHY_MODE_HDMI, - }; - - enum phy_media { -@@ -60,11 +62,14 @@ enum phy_media { - * the DisplayPort protocol. - * @lvds: Configuration set applicable for phys supporting - * the LVDS phy mode. -+ * @hdmi: Configuration set applicable for phys supporting -+ * the HDMI phy mode. - */ - union phy_configure_opts { - struct phy_configure_opts_mipi_dphy mipi_dphy; - struct phy_configure_opts_dp dp; - struct phy_configure_opts_lvds lvds; -+ struct phy_configure_opts_hdmi hdmi; - }; - - /** --- -2.34.1 - -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH v19 3/8] dt-bindings: display: bridge: Add Cadence MHDP8501 -From: Sandor Yu <Sandor.yu@nxp.com> -Date: Tue, 26 Nov 2024 22:11:48 +0800 -Message-Id: <e495a40a0add052d4f8cdeb4a81ea7408cdccaf6.1732627815.git.Sandor.yu@nxp.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -Add bindings for Cadence MHDP8501 DisplayPort/HDMI bridge. - -Signed-off-by: Sandor Yu <Sandor.yu@nxp.com> ---- -v18->v19: -- move data-lanes property to endpoint of port@1 - -v17->v18: -- remove lane-mapping and replace it with data-lanes -- remove r-b tag as property changed. - -v16->v17: -- Add lane-mapping property - -v9->v16: - *No change - - .../display/bridge/cdns,mhdp8501.yaml | 120 ++++++++++++++++++ - 1 file changed, 120 insertions(+) - create mode 100644 Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml - -diff --git a/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml b/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml -new file mode 100644 -index 0000000000000..24abd8447a28c ---- /dev/null -+++ b/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml -@@ -0,0 +1,120 @@ -+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/display/bridge/cdns,mhdp8501.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: Cadence MHDP8501 DP/HDMI bridge -+ -+maintainers: -+ - Sandor Yu <Sandor.yu@nxp.com> -+ -+description: -+ Cadence MHDP8501 DisplayPort/HDMI interface. -+ -+properties: -+ compatible: -+ enum: -+ - fsl,imx8mq-mhdp8501 -+ -+ reg: -+ maxItems: 1 -+ -+ clocks: -+ maxItems: 1 -+ description: MHDP8501 DP/HDMI APB clock. -+ -+ phys: -+ maxItems: 1 -+ description: -+ phandle to the DP/HDMI PHY -+ -+ interrupts: -+ items: -+ - description: Hotplug cable plugin. -+ - description: Hotplug cable plugout. -+ -+ interrupt-names: -+ items: -+ - const: plug_in -+ - const: plug_out -+ -+ ports: -+ $ref: /schemas/graph.yaml#/properties/ports -+ -+ properties: -+ port@0: -+ $ref: /schemas/graph.yaml#/properties/port -+ description: -+ Input port from display controller output. -+ -+ port@1: -+ $ref: /schemas/graph.yaml#/$defs/port-base -+ unevaluatedProperties: false -+ description: -+ Output port to DisplayPort or HDMI connector. -+ -+ properties: -+ endpoint: -+ $ref: /schemas/media/video-interfaces.yaml# -+ unevaluatedProperties: false -+ -+ properties: -+ data-lanes: -+ $ref: /schemas/media/video-interfaces.yaml#/properties/data-lanes -+ minItems: 4 -+ maxItems: 4 -+ description: Lane reordering for HDMI or DisplayPort interface. -+ required: -+ - data-lanes -+ required: -+ - port@0 -+ - port@1 -+ -+required: -+ - compatible -+ - reg -+ - clocks -+ - interrupts -+ - interrupt-names -+ - phys -+ - ports -+ -+additionalProperties: false -+ -+examples: -+ - | -+ #include <dt-bindings/clock/imx8mq-clock.h> -+ #include <dt-bindings/interrupt-controller/arm-gic.h> -+ -+ mhdp: display-bridge@32c00000 { -+ compatible = "fsl,imx8mq-mhdp8501"; -+ reg = <0x32c00000 0x100000>; -+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>, -+ <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>; -+ interrupt-names = "plug_in", "plug_out"; -+ clocks = <&clk IMX8MQ_CLK_DISP_APB_ROOT>; -+ phys = <&mdhp_phy>; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ port@0 { -+ reg = <0>; -+ -+ mhdp_in: endpoint { -+ remote-endpoint = <&dcss_out>; -+ }; -+ }; -+ -+ port@1 { -+ reg = <1>; -+ -+ mhdp_out: endpoint { -+ remote-endpoint = <&dp_connector>; -+ data-lanes = <2 1 0 3>; -+ }; -+ }; -+ }; -+ }; --- -2.34.1 - -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH v19 4/8] drm: bridge: Cadence: Add MHDP8501 DP/HDMI driver -From: Sandor Yu <Sandor.yu@nxp.com> -Date: Tue, 26 Nov 2024 22:11:49 +0800 -Message-Id: <e32c909ea8744fc5ea89aa3b4eed501efbaad1c3.1732627815.git.Sandor.yu@nxp.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -Add a new DRM DisplayPort and HDMI bridge driver for Candence MHDP8501 -used in i.MX8MQ SOC. MHDP8501 could support HDMI or DisplayPort -standards according embedded Firmware running in the uCPU. - -For iMX8MQ SOC, the DisplayPort/HDMI FW was loaded and activated by -SOC's ROM code. Bootload binary included respective specific firmware -is required. - -Driver will check display connector type and -then load the corresponding driver. - -Signed-off-by: Sandor Yu <Sandor.yu@nxp.com> ---- -v18->v19: -- Get endpoint for data-lanes as it had move to endpoint of port@1 -- Update clock management as devm_clk_get_enabled() introduced. -- Fix clear_infoframe() function is not work issue. -- Manage PHY power state via phy_power_on() and phy_power_off(). - -v17->v18: -- MHDP8501 HDMI and DP commands that need access mailbox are rewrited - with new API functions created in patch #1. -- replace lane-mapping with data-lanes, use the value from data-lanes - to reorder HDMI and DP lane mapping. -- create I2C adapter for HDMI SCDC, remove cdns_hdmi_scdc_write() function. -- Rewrite cdns_hdmi_sink_config() function, use HDMI SCDC helper function - drm_scdc_set_high_tmds_clock_ratio() and drm_scdc_set_scrambling() - to config HDMI sink TMDS. -- Remove struct video_info from HDMI driver. -- Remove tmds_char_rate_valid() be called in bridge_mode_valid(), - community had patch in reviewing to implement the function. -- Remove warning message print when get unknown HPD cable status. -- Add more detail comments for HDP plugin and plugout interrupt. -- use dev_dbg to repleace DRM_INFO when cable HPD status changed. -- Remove t-b tag as above code change. - - drivers/gpu/drm/bridge/cadence/Kconfig | 16 + - drivers/gpu/drm/bridge/cadence/Makefile | 2 + - .../drm/bridge/cadence/cdns-mhdp8501-core.c | 322 ++++++++ - .../drm/bridge/cadence/cdns-mhdp8501-core.h | 376 +++++++++ - .../gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c | 686 ++++++++++++++++ - .../drm/bridge/cadence/cdns-mhdp8501-hdmi.c | 764 ++++++++++++++++++ - 6 files changed, 2166 insertions(+) - create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.c - create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.h - create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c - create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c - -diff --git a/drivers/gpu/drm/bridge/cadence/Kconfig b/drivers/gpu/drm/bridge/cadence/Kconfig -index 1b315593a6d73..dc7a0466bb020 100644 ---- a/drivers/gpu/drm/bridge/cadence/Kconfig -+++ b/drivers/gpu/drm/bridge/cadence/Kconfig -@@ -55,3 +55,19 @@ config DRM_CDNS_MHDP8546_J721E - initializes the J721E Display Port and sets up the - clock and data muxes. - endif -+ -+config DRM_CDNS_MHDP8501 -+ tristate "Cadence MHDP8501 DP/HDMI bridge" -+ select DRM_KMS_HELPER -+ select DRM_PANEL_BRIDGE -+ select DRM_DISPLAY_DP_HELPER -+ select DRM_DISPLAY_HELPER -+ select CDNS_MHDP_HELPER -+ select DRM_CDNS_AUDIO -+ depends on OF -+ help -+ Support Cadence MHDP8501 DisplayPort/HDMI bridge. -+ Cadence MHDP8501 support one or more protocols, -+ including DisplayPort and HDMI. -+ To use the DP and HDMI drivers, their respective -+ specific firmware is required. -diff --git a/drivers/gpu/drm/bridge/cadence/Makefile b/drivers/gpu/drm/bridge/cadence/Makefile -index 087dc074820d7..02c1a9f3cf6fc 100644 ---- a/drivers/gpu/drm/bridge/cadence/Makefile -+++ b/drivers/gpu/drm/bridge/cadence/Makefile -@@ -6,3 +6,5 @@ obj-$(CONFIG_CDNS_MHDP_HELPER) += cdns-mhdp-helper.o - obj-$(CONFIG_DRM_CDNS_MHDP8546) += cdns-mhdp8546.o - cdns-mhdp8546-y := cdns-mhdp8546-core.o cdns-mhdp8546-hdcp.o - cdns-mhdp8546-$(CONFIG_DRM_CDNS_MHDP8546_J721E) += cdns-mhdp8546-j721e.o -+obj-$(CONFIG_DRM_CDNS_MHDP8501) += cdns-mhdp8501.o -+cdns-mhdp8501-y := cdns-mhdp8501-core.o cdns-mhdp8501-dp.o cdns-mhdp8501-hdmi.o -diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.c -new file mode 100644 -index 0000000000000..c51696b586dd0 ---- /dev/null -+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.c -@@ -0,0 +1,322 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Cadence Display Port Interface (DP) driver -+ * -+ * Copyright (C) 2023-2024 NXP Semiconductor, Inc. -+ * -+ */ -+#include <drm/drm_of.h> -+#include <drm/drm_print.h> -+#include <linux/clk.h> -+#include <linux/irq.h> -+#include <linux/mutex.h> -+#include <linux/of_device.h> -+#include <linux/platform_device.h> -+#include <linux/phy/phy.h> -+ -+#include "cdns-mhdp8501-core.h" -+ -+static int cdns_mhdp8501_read_hpd(struct cdns_mhdp8501_device *mhdp) -+{ -+ u8 status; -+ int ret; -+ -+ ret = cdns_mhdp_mailbox_send_recv(&mhdp->base, MB_MODULE_ID_GENERAL, -+ GENERAL_GET_HPD_STATE, -+ 0, NULL, sizeof(status), &status); -+ if (ret) { -+ dev_err(mhdp->dev, "read hpd failed: %d\n", ret); -+ return ret; -+ } -+ -+ return status; -+} -+ -+enum drm_connector_status cdns_mhdp8501_detect(struct cdns_mhdp8501_device *mhdp) -+{ -+ u8 hpd = 0xf; -+ -+ hpd = cdns_mhdp8501_read_hpd(mhdp); -+ if (hpd == 1) -+ return connector_status_connected; -+ else if (hpd == 0) -+ return connector_status_disconnected; -+ -+ return connector_status_unknown; -+} -+ -+static void hotplug_work_func(struct work_struct *work) -+{ -+ struct cdns_mhdp8501_device *mhdp = container_of(work, -+ struct cdns_mhdp8501_device, -+ hotplug_work.work); -+ enum drm_connector_status status = cdns_mhdp8501_detect(mhdp); -+ -+ drm_bridge_hpd_notify(&mhdp->bridge, status); -+ -+ /* -+ * iMX8MQ has two HPD interrupts: one for plugout and one for plugin. -+ * These interrupts cannot be masked and cleaned, so we must enable one -+ * and disable the other to avoid continuous interrupt generation. -+ */ -+ if (status == connector_status_connected) { -+ /* Cable connected */ -+ dev_dbg(mhdp->dev, "HDMI/DP Cable Plug In\n"); -+ enable_irq(mhdp->irq[IRQ_OUT]); -+ -+ /* Reset HDMI/DP link with sink */ -+ if (mhdp->connector_type == DRM_MODE_CONNECTOR_HDMIA) -+ cdns_hdmi_reset_link(mhdp); -+ else -+ cdns_dp_check_link_state(mhdp); -+ -+ } else if (status == connector_status_disconnected) { -+ /* Cable Disconnected */ -+ dev_dbg(mhdp->dev, "HDMI/DP Cable Plug Out\n"); -+ enable_irq(mhdp->irq[IRQ_IN]); -+ } -+} -+ -+static irqreturn_t cdns_mhdp8501_irq_thread(int irq, void *data) -+{ -+ struct cdns_mhdp8501_device *mhdp = data; -+ -+ disable_irq_nosync(irq); -+ -+ mod_delayed_work(system_wq, &mhdp->hotplug_work, -+ msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS)); -+ -+ return IRQ_HANDLED; -+} -+ -+#define DATA_LANES_COUNT 4 -+static int cdns_mhdp8501_dt_parse(struct cdns_mhdp8501_device *mhdp, -+ struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct device_node *np = dev->of_node; -+ struct device_node *remote, *endpoint; -+ u32 data_lanes[DATA_LANES_COUNT]; -+ u32 lane_value; -+ int ret, i; -+ -+ remote = of_graph_get_remote_node(np, 1, 0); -+ if (!remote) { -+ dev_err(dev, "fail to get remote node\n"); -+ of_node_put(remote); -+ return -EINVAL; -+ } -+ -+ /* get connector type */ -+ if (of_device_is_compatible(remote, "hdmi-connector")) { -+ mhdp->connector_type = DRM_MODE_CONNECTOR_HDMIA; -+ -+ } else if (of_device_is_compatible(remote, "dp-connector")) { -+ mhdp->connector_type = DRM_MODE_CONNECTOR_DisplayPort; -+ -+ } else { -+ dev_err(dev, "Unknown connector type\n"); -+ of_node_put(remote); -+ return -EINVAL; -+ } -+ -+ of_node_put(remote); -+ -+ endpoint = of_graph_get_endpoint_by_regs(np, 1, -1); -+ -+ /* Get the data lanes ordering */ -+ ret = of_property_count_u32_elems(endpoint, "data-lanes"); -+ if (ret < 0) -+ return -EINVAL; -+ if (ret != DATA_LANES_COUNT) { -+ dev_err(dev, "expected 4 data lanes\n"); -+ return -EINVAL; -+ } -+ -+ ret = of_property_read_u32_array(endpoint, "data-lanes", -+ data_lanes, DATA_LANES_COUNT); -+ if (ret) -+ return -EINVAL; -+ -+ mhdp->lane_mapping = 0; -+ for (i = 0; i < DATA_LANES_COUNT; i++) { -+ lane_value = (data_lanes[i] >= 0 && data_lanes[i] <= 3) ? data_lanes[i] : 0; -+ mhdp->lane_mapping |= lane_value << (i * 2); -+ } -+ -+ return true; -+} -+ -+static int cdns_mhdp8501_add_bridge(struct cdns_mhdp8501_device *mhdp) -+{ -+ mhdp->bridge.type = mhdp->connector_type; -+ mhdp->bridge.driver_private = mhdp; -+ mhdp->bridge.of_node = mhdp->dev->of_node; -+ mhdp->bridge.vendor = "NXP"; -+ mhdp->bridge.product = "i.MX8"; -+ mhdp->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | -+ DRM_BRIDGE_OP_HPD; -+ -+ if (mhdp->connector_type == DRM_MODE_CONNECTOR_HDMIA) { -+ mhdp->bridge.funcs = &cdns_hdmi_bridge_funcs; -+ mhdp->bridge.ops |= DRM_BRIDGE_OP_HDMI; -+ mhdp->bridge.ddc = cdns_hdmi_i2c_adapter(mhdp); -+ } else if (mhdp->connector_type == DRM_MODE_CONNECTOR_DisplayPort) { -+ mhdp->bridge.funcs = &cdns_dp_bridge_funcs; -+ } else { -+ dev_err(mhdp->dev, "Unsupported connector type!\n"); -+ return -EINVAL; -+ } -+ -+ drm_bridge_add(&mhdp->bridge); -+ -+ return 0; -+} -+ -+static int cdns_mhdp8501_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct cdns_mhdp8501_device *mhdp; -+ struct resource *res; -+ enum phy_mode phy_mode; -+ u32 reg; -+ int ret; -+ -+ mhdp = devm_kzalloc(dev, sizeof(*mhdp), GFP_KERNEL); -+ if (!mhdp) -+ return -ENOMEM; -+ -+ mhdp->dev = dev; -+ -+ INIT_DELAYED_WORK(&mhdp->hotplug_work, hotplug_work_func); -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) -+ return -ENODEV; -+ -+ mhdp->regs = devm_ioremap(dev, res->start, resource_size(res)); -+ if (IS_ERR(mhdp->regs)) -+ return PTR_ERR(mhdp->regs); -+ -+ ret = cdns_mhdp8501_dt_parse(mhdp, pdev); -+ if (ret < 0) -+ return -EINVAL; -+ -+ mhdp->phy = devm_of_phy_get_by_index(dev, pdev->dev.of_node, 0); -+ if (IS_ERR(mhdp->phy)) -+ return dev_err_probe(dev, PTR_ERR(mhdp->phy), "no PHY configured\n"); -+ -+ mhdp->irq[IRQ_IN] = platform_get_irq_byname(pdev, "plug_in"); -+ if (mhdp->irq[IRQ_IN] < 0) -+ return dev_err_probe(dev, mhdp->irq[IRQ_IN], "No plug_in irq number\n"); -+ -+ mhdp->irq[IRQ_OUT] = platform_get_irq_byname(pdev, "plug_out"); -+ if (mhdp->irq[IRQ_OUT] < 0) -+ return dev_err_probe(dev, mhdp->irq[IRQ_OUT], "No plug_out irq number\n"); -+ -+ irq_set_status_flags(mhdp->irq[IRQ_IN], IRQ_NOAUTOEN); -+ ret = devm_request_threaded_irq(dev, mhdp->irq[IRQ_IN], -+ NULL, cdns_mhdp8501_irq_thread, -+ IRQF_ONESHOT, dev_name(dev), mhdp); -+ if (ret < 0) { -+ dev_err(dev, "can't claim irq %d\n", mhdp->irq[IRQ_IN]); -+ return -EINVAL; -+ } -+ -+ irq_set_status_flags(mhdp->irq[IRQ_OUT], IRQ_NOAUTOEN); -+ ret = devm_request_threaded_irq(dev, mhdp->irq[IRQ_OUT], -+ NULL, cdns_mhdp8501_irq_thread, -+ IRQF_ONESHOT, dev_name(dev), mhdp); -+ if (ret < 0) { -+ dev_err(dev, "can't claim irq %d\n", mhdp->irq[IRQ_OUT]); -+ return -EINVAL; -+ } -+ -+ /* cdns_mhdp8501_dt_parse() ensures connector_type is valid */ -+ if (mhdp->connector_type == DRM_MODE_CONNECTOR_DisplayPort) -+ phy_mode = PHY_MODE_DP; -+ else if (mhdp->connector_type == DRM_MODE_CONNECTOR_HDMIA) -+ phy_mode = PHY_MODE_HDMI; -+ -+ dev_set_drvdata(dev, mhdp); -+ -+ /* init base struct for access mhdp mailbox */ -+ mhdp->base.dev = mhdp->dev; -+ mhdp->base.regs = mhdp->regs; -+ -+ if (mhdp->connector_type == DRM_MODE_CONNECTOR_DisplayPort) { -+ drm_dp_aux_init(&mhdp->dp.aux); -+ mhdp->dp.aux.name = "mhdp8501_dp_aux"; -+ mhdp->dp.aux.dev = dev; -+ mhdp->dp.aux.transfer = cdns_dp_aux_transfer; -+ } -+ -+ /* Enable APB clock */ -+ mhdp->apb_clk = devm_clk_get_enabled(dev, NULL); -+ if (IS_ERR(mhdp->apb_clk)) -+ return dev_err_probe(dev, PTR_ERR(mhdp->apb_clk), -+ "couldn't get apb clk\n"); -+ /* -+ * Wait for the KEEP_ALIVE "message" on the first 8 bits. -+ * Updated each sched "tick" (~2ms) -+ */ -+ ret = readl_poll_timeout(mhdp->regs + KEEP_ALIVE, reg, -+ reg & CDNS_KEEP_ALIVE_MASK, 500, -+ CDNS_KEEP_ALIVE_TIMEOUT); -+ if (ret) { -+ dev_err(dev, "device didn't give any life sign: reg %d\n", reg); -+ return ret; -+ } -+ -+ ret = phy_init(mhdp->phy); -+ if (ret) { -+ dev_err(dev, "Failed to initialize PHY: %d\n", ret); -+ return ret; -+ } -+ -+ ret = phy_set_mode(mhdp->phy, phy_mode); -+ if (ret) { -+ dev_err(dev, "Failed to configure PHY: %d\n", ret); -+ return ret; -+ } -+ -+ /* Enable cable hotplug detect */ -+ if (cdns_mhdp8501_read_hpd(mhdp)) -+ enable_irq(mhdp->irq[IRQ_OUT]); -+ else -+ enable_irq(mhdp->irq[IRQ_IN]); -+ -+ return cdns_mhdp8501_add_bridge(mhdp); -+} -+ -+static void cdns_mhdp8501_remove(struct platform_device *pdev) -+{ -+ struct cdns_mhdp8501_device *mhdp = platform_get_drvdata(pdev); -+ -+ if (mhdp->connector_type == DRM_MODE_CONNECTOR_DisplayPort) -+ cdns_dp_aux_destroy(mhdp); -+ -+ drm_bridge_remove(&mhdp->bridge); -+} -+ -+static const struct of_device_id cdns_mhdp8501_dt_ids[] = { -+ { .compatible = "fsl,imx8mq-mhdp8501", -+ }, -+ { }, -+}; -+MODULE_DEVICE_TABLE(of, cdns_mhdp8501_dt_ids); -+ -+static struct platform_driver cdns_mhdp8501_driver = { -+ .probe = cdns_mhdp8501_probe, -+ .remove = cdns_mhdp8501_remove, -+ .driver = { -+ .name = "cdns-mhdp8501", -+ .of_match_table = cdns_mhdp8501_dt_ids, -+ }, -+}; -+ -+module_platform_driver(cdns_mhdp8501_driver); -+ -+MODULE_AUTHOR("Sandor Yu <sandor.yu@nxp.com>"); -+MODULE_DESCRIPTION("Cadence MHDP8501 bridge driver"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.h b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.h -new file mode 100644 -index 0000000000000..a8b7e54f629e2 ---- /dev/null -+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.h -@@ -0,0 +1,376 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Cadence MHDP 8501 Common head file -+ * -+ * Copyright (C) 2019-2024 NXP Semiconductor, Inc. -+ * -+ */ -+ -+#ifndef _CDNS_MHDP8501_CORE_H_ -+#define _CDNS_MHDP8501_CORE_H_ -+ -+#include <drm/bridge/cdns-mhdp-helper.h> -+#include <drm/drm_bridge.h> -+#include <drm/drm_connector.h> -+#include <drm/display/drm_dp_helper.h> -+#include <linux/bitops.h> -+#include <linux/i2c.h> -+ -+#define ADDR_IMEM 0x10000 -+#define ADDR_DMEM 0x20000 -+ -+/* APB CFG addr */ -+#define APB_CTRL 0 -+#define XT_INT_CTRL 0x04 -+#define MAILBOX_FULL_ADDR 0x08 -+#define MAILBOX_EMPTY_ADDR 0x0c -+#define MAILBOX0_WR_DATA 0x10 -+#define MAILBOX0_RD_DATA 0x14 -+#define KEEP_ALIVE 0x18 -+#define VER_L 0x1c -+#define VER_H 0x20 -+#define VER_LIB_L_ADDR 0x24 -+#define VER_LIB_H_ADDR 0x28 -+#define SW_DEBUG_L 0x2c -+#define SW_DEBUG_H 0x30 -+#define MAILBOX_INT_MASK 0x34 -+#define MAILBOX_INT_STATUS 0x38 -+#define SW_CLK_L 0x3c -+#define SW_CLK_H 0x40 -+#define SW_EVENTS0 0x44 -+#define SW_EVENTS1 0x48 -+#define SW_EVENTS2 0x4c -+#define SW_EVENTS3 0x50 -+#define XT_OCD_CTRL 0x60 -+#define APB_INT_MASK 0x6c -+#define APB_STATUS_MASK 0x70 -+ -+/* Source phy comp */ -+#define PHY_DATA_SEL 0x0818 -+#define LANES_CONFIG 0x0814 -+ -+/* Source CAR Addr */ -+#define SOURCE_HDTX_CAR 0x0900 -+#define SOURCE_DPTX_CAR 0x0904 -+#define SOURCE_PHY_CAR 0x0908 -+#define SOURCE_CEC_CAR 0x090c -+#define SOURCE_CBUS_CAR 0x0910 -+#define SOURCE_PKT_CAR 0x0918 -+#define SOURCE_AIF_CAR 0x091c -+#define SOURCE_CIPHER_CAR 0x0920 -+#define SOURCE_CRYPTO_CAR 0x0924 -+ -+/* clock meters addr */ -+#define CM_CTRL 0x0a00 -+#define CM_I2S_CTRL 0x0a04 -+#define CM_SPDIF_CTRL 0x0a08 -+#define CM_VID_CTRL 0x0a0c -+#define CM_LANE_CTRL 0x0a10 -+#define I2S_NM_STABLE 0x0a14 -+#define I2S_NCTS_STABLE 0x0a18 -+#define SPDIF_NM_STABLE 0x0a1c -+#define SPDIF_NCTS_STABLE 0x0a20 -+#define NMVID_MEAS_STABLE 0x0a24 -+#define I2S_MEAS 0x0a40 -+#define SPDIF_MEAS 0x0a80 -+#define NMVID_MEAS 0x0ac0 -+ -+/* source vif addr */ -+#define BND_HSYNC2VSYNC 0x0b00 -+#define HSYNC2VSYNC_F1_L1 0x0b04 -+#define HSYNC2VSYNC_STATUS 0x0b0c -+#define HSYNC2VSYNC_POL_CTRL 0x0b10 -+ -+/* MHDP TX_top_comp */ -+#define SCHEDULER_H_SIZE 0x1000 -+#define SCHEDULER_V_SIZE 0x1004 -+#define HDTX_SIGNAL_FRONT_WIDTH 0x100c -+#define HDTX_SIGNAL_SYNC_WIDTH 0x1010 -+#define HDTX_SIGNAL_BACK_WIDTH 0x1014 -+#define HDTX_CONTROLLER 0x1018 -+#define HDTX_HPD 0x1020 -+#define HDTX_CLOCK_REG_0 0x1024 -+#define HDTX_CLOCK_REG_1 0x1028 -+ -+/* DPTX hpd addr */ -+#define HPD_IRQ_DET_MIN_TIMER 0x2100 -+#define HPD_IRQ_DET_MAX_TIMER 0x2104 -+#define HPD_UNPLGED_DET_MIN_TIMER 0x2108 -+#define HPD_STABLE_TIMER 0x210c -+#define HPD_FILTER_TIMER 0x2110 -+#define HPD_EVENT_MASK 0x211c -+#define HPD_EVENT_DET 0x2120 -+ -+/* DPTX framer addr */ -+#define DP_FRAMER_GLOBAL_CONFIG 0x2200 -+#define DP_SW_RESET 0x2204 -+#define DP_FRAMER_TU 0x2208 -+#define DP_FRAMER_PXL_REPR 0x220c -+#define DP_FRAMER_SP 0x2210 -+#define AUDIO_PACK_CONTROL 0x2214 -+#define DP_VC_TABLE(x) (0x2218 + ((x) << 2)) -+#define DP_VB_ID 0x2258 -+#define DP_MTPH_LVP_CONTROL 0x225c -+#define DP_MTPH_SYMBOL_VALUES 0x2260 -+#define DP_MTPH_ECF_CONTROL 0x2264 -+#define DP_MTPH_ACT_CONTROL 0x2268 -+#define DP_MTPH_STATUS 0x226c -+#define DP_INTERRUPT_SOURCE 0x2270 -+#define DP_INTERRUPT_MASK 0x2274 -+#define DP_FRONT_BACK_PORCH 0x2278 -+#define DP_BYTE_COUNT 0x227c -+ -+/* DPTX stream addr */ -+#define MSA_HORIZONTAL_0 0x2280 -+#define MSA_HORIZONTAL_1 0x2284 -+#define MSA_VERTICAL_0 0x2288 -+#define MSA_VERTICAL_1 0x228c -+#define MSA_MISC 0x2290 -+#define STREAM_CONFIG 0x2294 -+#define AUDIO_PACK_STATUS 0x2298 -+#define VIF_STATUS 0x229c -+#define PCK_STUFF_STATUS_0 0x22a0 -+#define PCK_STUFF_STATUS_1 0x22a4 -+#define INFO_PACK_STATUS 0x22a8 -+#define RATE_GOVERNOR_STATUS 0x22ac -+#define DP_HORIZONTAL 0x22b0 -+#define DP_VERTICAL_0 0x22b4 -+#define DP_VERTICAL_1 0x22b8 -+#define DP_BLOCK_SDP 0x22bc -+ -+/* DPTX glbl addr */ -+#define DPTX_LANE_EN 0x2300 -+#define DPTX_ENHNCD 0x2304 -+#define DPTX_INT_MASK 0x2308 -+#define DPTX_INT_STATUS 0x230c -+ -+/* DP AUX Addr */ -+#define DP_AUX_HOST_CONTROL 0x2800 -+#define DP_AUX_INTERRUPT_SOURCE 0x2804 -+#define DP_AUX_INTERRUPT_MASK 0x2808 -+#define DP_AUX_SWAP_INVERSION_CONTROL 0x280c -+#define DP_AUX_SEND_NACK_TRANSACTION 0x2810 -+#define DP_AUX_CLEAR_RX 0x2814 -+#define DP_AUX_CLEAR_TX 0x2818 -+#define DP_AUX_TIMER_STOP 0x281c -+#define DP_AUX_TIMER_CLEAR 0x2820 -+#define DP_AUX_RESET_SW 0x2824 -+#define DP_AUX_DIVIDE_2M 0x2828 -+#define DP_AUX_TX_PREACHARGE_LENGTH 0x282c -+#define DP_AUX_FREQUENCY_1M_MAX 0x2830 -+#define DP_AUX_FREQUENCY_1M_MIN 0x2834 -+#define DP_AUX_RX_PRE_MIN 0x2838 -+#define DP_AUX_RX_PRE_MAX 0x283c -+#define DP_AUX_TIMER_PRESET 0x2840 -+#define DP_AUX_NACK_FORMAT 0x2844 -+#define DP_AUX_TX_DATA 0x2848 -+#define DP_AUX_RX_DATA 0x284c -+#define DP_AUX_TX_STATUS 0x2850 -+#define DP_AUX_RX_STATUS 0x2854 -+#define DP_AUX_RX_CYCLE_COUNTER 0x2858 -+#define DP_AUX_MAIN_STATES 0x285c -+#define DP_AUX_MAIN_TIMER 0x2860 -+#define DP_AUX_AFE_OUT 0x2864 -+ -+/* source pif addr */ -+#define SOURCE_PIF_WR_ADDR 0x30800 -+#define SOURCE_PIF_WR_REQ 0x30804 -+#define SOURCE_PIF_RD_ADDR 0x30808 -+#define SOURCE_PIF_RD_REQ 0x3080c -+#define SOURCE_PIF_DATA_WR 0x30810 -+#define SOURCE_PIF_DATA_RD 0x30814 -+#define SOURCE_PIF_FIFO1_FLUSH 0x30818 -+#define SOURCE_PIF_FIFO2_FLUSH 0x3081c -+#define SOURCE_PIF_STATUS 0x30820 -+#define SOURCE_PIF_INTERRUPT_SOURCE 0x30824 -+#define SOURCE_PIF_INTERRUPT_MASK 0x30828 -+#define SOURCE_PIF_PKT_ALLOC_REG 0x3082c -+#define SOURCE_PIF_PKT_ALLOC_WR_EN 0x30830 -+#define SOURCE_PIF_SW_RESET 0x30834 -+ -+#define LINK_TRAINING_NOT_ACTIV 0 -+#define LINK_TRAINING_RUN 1 -+#define LINK_TRAINING_RESTART 2 -+ -+#define CONTROL_VIDEO_IDLE 0 -+#define CONTROL_VIDEO_VALID 1 -+ -+#define INTERLACE_FMT_DET BIT(12) -+#define VIF_BYPASS_INTERLACE BIT(13) -+#define TU_CNT_RST_EN BIT(15) -+#define INTERLACE_DTCT_WIN 0x20 -+ -+#define DP_FRAMER_SP_INTERLACE_EN BIT(2) -+#define DP_FRAMER_SP_HSP BIT(1) -+#define DP_FRAMER_SP_VSP BIT(0) -+ -+/* Capability */ -+#define AUX_HOST_INVERT 3 -+#define FAST_LT_SUPPORT 1 -+#define FAST_LT_NOT_SUPPORT 0 -+#define LANE_MAPPING_FLIPPED 0xe4 -+#define ENHANCED 1 -+#define SCRAMBLER_EN BIT(4) -+ -+#define FULL_LT_STARTED BIT(0) -+#define FASE_LT_STARTED BIT(1) -+#define CLK_RECOVERY_FINISHED BIT(2) -+#define EQ_PHASE_FINISHED BIT(3) -+#define FASE_LT_START_FINISHED BIT(4) -+#define CLK_RECOVERY_FAILED BIT(5) -+#define EQ_PHASE_FAILED BIT(6) -+#define FASE_LT_FAILED BIT(7) -+ -+#define TU_SIZE 30 -+#define CDNS_DP_MAX_LINK_RATE 540000 -+ -+#define F_HDMI2_CTRL_IL_MODE(x) (((x) & ((1 << 1) - 1)) << 19) -+#define F_HDMI2_PREAMBLE_EN(x) (((x) & ((1 << 1) - 1)) << 18) -+#define F_HDMI_ENCODING(x) (((x) & ((1 << 2) - 1)) << 16) -+#define F_DATA_EN(x) (((x) & ((1 << 1) - 1)) << 15) -+#define F_CLEAR_AVMUTE(x) (((x) & ((1 << 1) - 1)) << 14) -+#define F_SET_AVMUTE(x) (((x) & ((1 << 1) - 1)) << 13) -+#define F_GCP_EN(x) (((x) & ((1 << 1) - 1)) << 12) -+#define F_BCH_EN(x) (((x) & ((1 << 1) - 1)) << 11) -+#define F_PIC_3D(x) (((x) & ((1 << 4) - 1)) << 7) -+#define F_VIF_DATA_WIDTH(x) (((x) & ((1 << 2) - 1)) << 2) -+#define F_HDMI_MODE(x) (((x) & ((1 << 2) - 1)) << 0) -+ -+#define F_SOURCE_PHY_MHDP_SEL(x) (((x) & ((1 << 2) - 1)) << 3) -+ -+#define F_HPD_GLITCH_WIDTH(x) (((x) & ((1 << 8) - 1)) << 12) -+#define F_PACKET_TYPE(x) (((x) & ((1 << 8) - 1)) << 8) -+#define F_HPD_VALID_WIDTH(x) (((x) & ((1 << 12) - 1)) << 0) -+ -+#define F_SOURCE_PHY_LANE3_SWAP(x) (((x) & ((1 << 2) - 1)) << 6) -+#define F_SOURCE_PHY_LANE2_SWAP(x) (((x) & ((1 << 2) - 1)) << 4) -+#define F_SOURCE_PHY_LANE1_SWAP(x) (((x) & ((1 << 2) - 1)) << 2) -+#define F_SOURCE_PHY_LANE0_SWAP(x) (((x) & ((1 << 2) - 1)) << 0) -+ -+#define F_ACTIVE_IDLE_TYPE(x) (((x) & ((1 << 1) - 1)) << 17) -+#define F_TYPE_VALID(x) (((x) & ((1 << 1) - 1)) << 16) -+#define F_PKT_ALLOC_ADDRESS(x) (((x) & ((1 << 4) - 1)) << 0) -+ -+#define F_FIFO1_FLUSH(x) (((x) & ((1 << 1) - 1)) << 0) -+#define F_PKT_ALLOC_WR_EN(x) (((x) & ((1 << 1) - 1)) << 0) -+#define F_DATA_WR(x) (x) -+#define F_WR_ADDR(x) (((x) & ((1 << 4) - 1)) << 0) -+#define F_HOST_WR(x) (((x) & ((1 << 1) - 1)) << 0) -+ -+/* Reference cycles when using lane clock as reference */ -+#define LANE_REF_CYC 0x8000 -+ -+/* HPD Debounce */ -+#define HOTPLUG_DEBOUNCE_MS 200 -+ -+/* HPD IRQ Index */ -+#define IRQ_IN 0 -+#define IRQ_OUT 1 -+#define IRQ_NUM 2 -+ -+/* FW check alive timeout */ -+#define CDNS_KEEP_ALIVE_TIMEOUT 2000 -+#define CDNS_KEEP_ALIVE_MASK GENMASK(7, 0) -+ -+enum voltage_swing_level { -+ VOLTAGE_LEVEL_0, -+ VOLTAGE_LEVEL_1, -+ VOLTAGE_LEVEL_2, -+ VOLTAGE_LEVEL_3, -+}; -+ -+enum pre_emphasis_level { -+ PRE_EMPHASIS_LEVEL_0, -+ PRE_EMPHASIS_LEVEL_1, -+ PRE_EMPHASIS_LEVEL_2, -+ PRE_EMPHASIS_LEVEL_3, -+}; -+ -+enum pattern_set { -+ PTS1 = BIT(0), -+ PTS2 = BIT(1), -+ PTS3 = BIT(2), -+ PTS4 = BIT(3), -+ DP_NONE = BIT(4) -+}; -+ -+enum vic_color_depth { -+ BCS_6 = 0x1, -+ BCS_8 = 0x2, -+ BCS_10 = 0x4, -+ BCS_12 = 0x8, -+ BCS_16 = 0x10, -+}; -+ -+enum vic_bt_type { -+ BT_601 = 0x0, -+ BT_709 = 0x1, -+}; -+ -+enum { -+ MODE_DVI, -+ MODE_HDMI_1_4, -+ MODE_HDMI_2_0, -+}; -+ -+struct video_info { -+ int bpc; -+ int color_fmt; -+}; -+ -+struct cdns_hdmi_i2c { -+ struct i2c_adapter adap; -+ -+ struct mutex lock; /* used to serialize data transfers */ -+ struct completion cmp; -+ u8 stat; -+ -+ u8 slave_reg; -+ bool is_regaddr; -+ bool is_segment; -+}; -+ -+struct cdns_mhdp8501_device { -+ struct cdns_mhdp_base base; -+ -+ struct device *dev; -+ void __iomem *regs; -+ struct drm_connector *curr_conn; -+ struct drm_bridge bridge; -+ struct clk *apb_clk; -+ struct phy *phy; -+ -+ struct video_info video_info; -+ -+ int irq[IRQ_NUM]; -+ struct delayed_work hotplug_work; -+ int connector_type; -+ u32 lane_mapping; -+ -+ union { -+ struct _dp_data { -+ u32 rate; -+ u8 num_lanes; -+ struct drm_dp_aux aux; -+ u8 dpcd[DP_RECEIVER_CAP_SIZE]; -+ } dp; -+ struct _hdmi_data { -+ u32 hdmi_type; -+ struct cdns_hdmi_i2c *i2c; -+ } hdmi; -+ }; -+}; -+ -+extern const struct drm_bridge_funcs cdns_dp_bridge_funcs; -+extern const struct drm_bridge_funcs cdns_hdmi_bridge_funcs; -+ -+enum drm_connector_status -+cdns_mhdp8501_detect(struct cdns_mhdp8501_device *mhdp); -+ -+ssize_t cdns_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg); -+int cdns_dp_aux_destroy(struct cdns_mhdp8501_device *mhdp); -+void cdns_dp_check_link_state(struct cdns_mhdp8501_device *mhdp); -+ -+void cdns_hdmi_reset_link(struct cdns_mhdp8501_device *mhdp); -+struct i2c_adapter *cdns_hdmi_i2c_adapter(struct cdns_mhdp8501_device *mhdp); -+#endif -diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c -new file mode 100644 -index 0000000000000..392bb65f6c9c1 ---- /dev/null -+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c -@@ -0,0 +1,686 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Cadence MHDP8501 DisplayPort(DP) bridge driver -+ * -+ * Copyright (C) 2019-2024 NXP Semiconductor, Inc. -+ * -+ */ -+#include <drm/drm_atomic_helper.h> -+#include <drm/drm_edid.h> -+#include <drm/drm_print.h> -+#include <linux/phy/phy.h> -+#include <linux/phy/phy-dp.h> -+ -+#include "cdns-mhdp8501-core.h" -+ -+#define LINK_TRAINING_TIMEOUT_MS 500 -+#define LINK_TRAINING_RETRY_MS 20 -+ -+ssize_t cdns_dp_aux_transfer(struct drm_dp_aux *aux, -+ struct drm_dp_aux_msg *msg) -+{ -+ struct cdns_mhdp8501_device *mhdp = dev_get_drvdata(aux->dev); -+ bool native = msg->request & (DP_AUX_NATIVE_WRITE & DP_AUX_NATIVE_READ); -+ int ret; -+ -+ /* Ignore address only message */ -+ if (!msg->size || !msg->buffer) { -+ msg->reply = native ? -+ DP_AUX_NATIVE_REPLY_ACK : DP_AUX_I2C_REPLY_ACK; -+ return msg->size; -+ } -+ -+ if (!native) { -+ dev_err(mhdp->dev, "%s: only native messages supported\n", __func__); -+ return -EINVAL; -+ } -+ -+ /* msg sanity check */ -+ if (msg->size > DP_AUX_MAX_PAYLOAD_BYTES) { -+ dev_err(mhdp->dev, "%s: invalid msg: size(%zu), request(%x)\n", -+ __func__, msg->size, (unsigned int)msg->request); -+ return -EINVAL; -+ } -+ -+ if (msg->request == DP_AUX_NATIVE_WRITE) { -+ const u8 *buf = msg->buffer; -+ int i; -+ -+ for (i = 0; i < msg->size; ++i) { -+ ret = cdns_mhdp_dpcd_write(&mhdp->base, -+ msg->address + i, buf[i]); -+ if (ret < 0) { -+ dev_err(mhdp->dev, "Failed to write DPCD\n"); -+ return ret; -+ } -+ } -+ msg->reply = DP_AUX_NATIVE_REPLY_ACK; -+ return msg->size; -+ } -+ -+ if (msg->request == DP_AUX_NATIVE_READ) { -+ ret = cdns_mhdp_dpcd_read(&mhdp->base, msg->address, -+ msg->buffer, msg->size); -+ if (ret < 0) -+ return ret; -+ msg->reply = DP_AUX_NATIVE_REPLY_ACK; -+ return msg->size; -+ } -+ return 0; -+} -+ -+int cdns_dp_aux_destroy(struct cdns_mhdp8501_device *mhdp) -+{ -+ drm_dp_aux_unregister(&mhdp->dp.aux); -+ -+ return 0; -+} -+ -+static int cdns_dp_get_msa_misc(struct video_info *video) -+{ -+ u32 msa_misc; -+ u8 color_space = 0; -+ u8 bpc = 0; -+ -+ switch (video->color_fmt) { -+ /* set YUV default color space conversion to BT601 */ -+ case DRM_COLOR_FORMAT_YCBCR444: -+ color_space = 6 + BT_601 * 8; -+ break; -+ case DRM_COLOR_FORMAT_YCBCR422: -+ color_space = 5 + BT_601 * 8; -+ break; -+ case DRM_COLOR_FORMAT_YCBCR420: -+ color_space = 5; -+ break; -+ case DRM_COLOR_FORMAT_RGB444: -+ default: -+ color_space = 0; -+ break; -+ }; -+ -+ switch (video->bpc) { -+ case 6: -+ bpc = 0; -+ break; -+ case 10: -+ bpc = 2; -+ break; -+ case 12: -+ bpc = 3; -+ break; -+ case 16: -+ bpc = 4; -+ break; -+ case 8: -+ default: -+ bpc = 1; -+ break; -+ }; -+ -+ msa_misc = (bpc << 5) | (color_space << 1); -+ -+ return msa_misc; -+} -+ -+static int cdns_dp_config_video(struct cdns_mhdp8501_device *mhdp, -+ const struct drm_display_mode *mode) -+{ -+ struct video_info *video = &mhdp->video_info; -+ bool h_sync_polarity, v_sync_polarity; -+ u64 symbol; -+ u32 val, link_rate, rem; -+ u8 bit_per_pix, tu_size_reg = TU_SIZE; -+ int ret; -+ -+ bit_per_pix = (video->color_fmt == DRM_COLOR_FORMAT_YCBCR422) ? -+ (video->bpc * 2) : (video->bpc * 3); -+ -+ link_rate = mhdp->dp.rate / 1000; -+ -+ ret = cdns_mhdp_reg_write(&mhdp->base, BND_HSYNC2VSYNC, VIF_BYPASS_INTERLACE); -+ if (ret) -+ goto err_config_video; -+ -+ ret = cdns_mhdp_reg_write(&mhdp->base, HSYNC2VSYNC_POL_CTRL, 0); -+ if (ret) -+ goto err_config_video; -+ -+ /* -+ * get a best tu_size and valid symbol: -+ * 1. chose Lclk freq(162Mhz, 270Mhz, 540Mhz), set TU to 32 -+ * 2. calculate VS(valid symbol) = TU * Pclk * Bpp / (Lclk * Lanes) -+ * 3. if VS > *.85 or VS < *.1 or VS < 2 or TU < VS + 4, then set -+ * TU += 2 and repeat 2nd step. -+ */ -+ do { -+ tu_size_reg += 2; -+ symbol = tu_size_reg * mode->clock * bit_per_pix; -+ do_div(symbol, mhdp->dp.num_lanes * link_rate * 8); -+ rem = do_div(symbol, 1000); -+ if (tu_size_reg > 64) { -+ ret = -EINVAL; -+ dev_err(mhdp->dev, "tu error, clk:%d, lanes:%d, rate:%d\n", -+ mode->clock, mhdp->dp.num_lanes, link_rate); -+ goto err_config_video; -+ } -+ } while ((symbol <= 1) || (tu_size_reg - symbol < 4) || -+ (rem > 850) || (rem < 100)); -+ -+ val = symbol + (tu_size_reg << 8); -+ val |= TU_CNT_RST_EN; -+ ret = cdns_mhdp_reg_write(&mhdp->base, DP_FRAMER_TU, val); -+ if (ret) -+ goto err_config_video; -+ -+ /* set the FIFO Buffer size */ -+ val = div_u64(mode->clock * (symbol + 1), 1000) + link_rate; -+ val /= (mhdp->dp.num_lanes * link_rate); -+ val = div_u64(8 * (symbol + 1), bit_per_pix) - val; -+ val += 2; -+ ret = cdns_mhdp_reg_write(&mhdp->base, DP_VC_TABLE(15), val); -+ -+ switch (video->bpc) { -+ case 6: -+ val = BCS_6; -+ break; -+ case 10: -+ val = BCS_10; -+ break; -+ case 12: -+ val = BCS_12; -+ break; -+ case 16: -+ val = BCS_16; -+ break; -+ case 8: -+ default: -+ val = BCS_8; -+ break; -+ }; -+ -+ val += video->color_fmt << 8; -+ ret = cdns_mhdp_reg_write(&mhdp->base, DP_FRAMER_PXL_REPR, val); -+ if (ret) -+ goto err_config_video; -+ -+ v_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NVSYNC); -+ h_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NHSYNC); -+ -+ val = h_sync_polarity ? DP_FRAMER_SP_HSP : 0; -+ val |= v_sync_polarity ? DP_FRAMER_SP_VSP : 0; -+ ret = cdns_mhdp_reg_write(&mhdp->base, DP_FRAMER_SP, val); -+ if (ret) -+ goto err_config_video; -+ -+ val = (mode->hsync_start - mode->hdisplay) << 16; -+ val |= mode->htotal - mode->hsync_end; -+ ret = cdns_mhdp_reg_write(&mhdp->base, DP_FRONT_BACK_PORCH, val); -+ if (ret) -+ goto err_config_video; -+ -+ val = mode->hdisplay * bit_per_pix / 8; -+ ret = cdns_mhdp_reg_write(&mhdp->base, DP_BYTE_COUNT, val); -+ if (ret) -+ goto err_config_video; -+ -+ val = mode->htotal | ((mode->htotal - mode->hsync_start) << 16); -+ ret = cdns_mhdp_reg_write(&mhdp->base, MSA_HORIZONTAL_0, val); -+ if (ret) -+ goto err_config_video; -+ -+ val = mode->hsync_end - mode->hsync_start; -+ val |= (mode->hdisplay << 16) | (h_sync_polarity << 15); -+ ret = cdns_mhdp_reg_write(&mhdp->base, MSA_HORIZONTAL_1, val); -+ if (ret) -+ goto err_config_video; -+ -+ val = mode->vtotal; -+ val |= (mode->vtotal - mode->vsync_start) << 16; -+ ret = cdns_mhdp_reg_write(&mhdp->base, MSA_VERTICAL_0, val); -+ if (ret) -+ goto err_config_video; -+ -+ val = mode->vsync_end - mode->vsync_start; -+ val |= (mode->vdisplay << 16) | (v_sync_polarity << 15); -+ ret = cdns_mhdp_reg_write(&mhdp->base, MSA_VERTICAL_1, val); -+ if (ret) -+ goto err_config_video; -+ -+ val = cdns_dp_get_msa_misc(video); -+ ret = cdns_mhdp_reg_write(&mhdp->base, MSA_MISC, val); -+ if (ret) -+ goto err_config_video; -+ -+ ret = cdns_mhdp_reg_write(&mhdp->base, STREAM_CONFIG, 1); -+ if (ret) -+ goto err_config_video; -+ -+ val = mode->hsync_end - mode->hsync_start; -+ val |= mode->hdisplay << 16; -+ ret = cdns_mhdp_reg_write(&mhdp->base, DP_HORIZONTAL, val); -+ if (ret) -+ goto err_config_video; -+ -+ val = mode->vdisplay; -+ val |= (mode->vtotal - mode->vsync_start) << 16; -+ ret = cdns_mhdp_reg_write(&mhdp->base, DP_VERTICAL_0, val); -+ if (ret) -+ goto err_config_video; -+ -+ val = mode->vtotal; -+ ret = cdns_mhdp_reg_write(&mhdp->base, DP_VERTICAL_1, val); -+ if (ret) -+ goto err_config_video; -+ -+ ret = cdns_mhdp_dp_reg_write_bit(&mhdp->base, DP_VB_ID, 2, 1, 0); -+ -+err_config_video: -+ if (ret) -+ dev_err(mhdp->dev, "config video failed: %d\n", ret); -+ return ret; -+} -+ -+static void cdns_dp_pixel_clk_reset(struct cdns_mhdp8501_device *mhdp) -+{ -+ u32 val; -+ -+ /* reset pixel clk */ -+ cdns_mhdp_reg_read(&mhdp->base, SOURCE_HDTX_CAR, &val); -+ cdns_mhdp_reg_write(&mhdp->base, SOURCE_HDTX_CAR, val & 0xFD); -+ cdns_mhdp_reg_write(&mhdp->base, SOURCE_HDTX_CAR, val); -+} -+ -+static int cdns_dp_set_video_status(struct cdns_mhdp8501_device *mhdp, int active) -+{ -+ u8 msg; -+ int ret; -+ -+ msg = !!active; -+ -+ ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX, -+ DPTX_SET_VIDEO, sizeof(msg), &msg); -+ if (ret) -+ dev_err(mhdp->dev, "set video status failed: %d\n", ret); -+ -+ return ret; -+} -+ -+static int cdns_dp_training_start(struct cdns_mhdp8501_device *mhdp) -+{ -+ unsigned long timeout; -+ u8 msg, event[2]; -+ int ret; -+ -+ msg = LINK_TRAINING_RUN; -+ -+ /* start training */ -+ ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX, -+ DPTX_TRAINING_CONTROL, sizeof(msg), &msg); -+ if (ret) -+ return ret; -+ -+ timeout = jiffies + msecs_to_jiffies(LINK_TRAINING_TIMEOUT_MS); -+ while (time_before(jiffies, timeout)) { -+ msleep(LINK_TRAINING_RETRY_MS); -+ ret = cdns_mhdp_mailbox_send_recv(&mhdp->base, MB_MODULE_ID_DP_TX, -+ DPTX_READ_EVENT, -+ 0, NULL, sizeof(event), event); -+ if (ret) -+ return ret; -+ -+ if (event[1] & CLK_RECOVERY_FAILED) -+ dev_err(mhdp->dev, "clock recovery failed\n"); -+ else if (event[1] & EQ_PHASE_FINISHED) -+ return 0; -+ } -+ -+ return -ETIMEDOUT; -+} -+ -+static int cdns_dp_get_training_status(struct cdns_mhdp8501_device *mhdp) -+{ -+ u8 status[13]; -+ int ret; -+ -+ ret = cdns_mhdp_mailbox_send_recv(&mhdp->base, MB_MODULE_ID_DP_TX, -+ DPTX_READ_LINK_STAT, -+ 0, NULL, sizeof(status), status); -+ if (ret) -+ return ret; -+ -+ mhdp->dp.rate = drm_dp_bw_code_to_link_rate(status[0]); -+ mhdp->dp.num_lanes = status[1]; -+ -+ return ret; -+} -+ -+static int cdns_dp_train_link(struct cdns_mhdp8501_device *mhdp) -+{ -+ int ret; -+ -+ ret = cdns_dp_training_start(mhdp); -+ if (ret) { -+ dev_err(mhdp->dev, "Failed to start training %d\n", ret); -+ return ret; -+ } -+ -+ ret = cdns_dp_get_training_status(mhdp); -+ if (ret) { -+ dev_err(mhdp->dev, "Failed to get training stat %d\n", ret); -+ return ret; -+ } -+ -+ dev_dbg(mhdp->dev, "rate:0x%x, lanes:%d\n", mhdp->dp.rate, -+ mhdp->dp.num_lanes); -+ return ret; -+} -+ -+static int cdns_dp_set_host_cap(struct cdns_mhdp8501_device *mhdp) -+{ -+ u8 msg[8]; -+ int ret; -+ -+ msg[0] = drm_dp_link_rate_to_bw_code(mhdp->dp.rate); -+ msg[1] = mhdp->dp.num_lanes | SCRAMBLER_EN; -+ msg[2] = VOLTAGE_LEVEL_2; -+ msg[3] = PRE_EMPHASIS_LEVEL_3; -+ msg[4] = PTS1 | PTS2 | PTS3 | PTS4; -+ msg[5] = FAST_LT_NOT_SUPPORT; -+ msg[6] = mhdp->lane_mapping; -+ msg[7] = ENHANCED; -+ -+ ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX, -+ DPTX_SET_HOST_CAPABILITIES, -+ sizeof(msg), msg); -+ if (ret) -+ dev_err(mhdp->dev, "set host cap failed: %d\n", ret); -+ -+ return ret; -+} -+ -+static int cdns_dp_get_edid_block(void *data, u8 *edid, -+ unsigned int block, size_t length) -+{ -+ struct cdns_mhdp8501_device *mhdp = data; -+ u8 msg[2], reg[2], i; -+ int ret; -+ -+ for (i = 0; i < 4; i++) { -+ msg[0] = block / 2; -+ msg[1] = block % 2; -+ -+ ret = cdns_mhdp_mailbox_send_recv_multi(&mhdp->base, -+ MB_MODULE_ID_DP_TX, -+ DPTX_GET_EDID, -+ sizeof(msg), msg, -+ DPTX_GET_EDID, -+ sizeof(reg), reg, -+ length, edid); -+ if (ret) -+ continue; -+ -+ if (reg[0] == length && reg[1] == block / 2) -+ break; -+ } -+ -+ if (ret) -+ dev_err(mhdp->dev, "get block[%d] edid failed: %d\n", -+ block, ret); -+ -+ return ret; -+} -+ -+static void cdns_dp_mode_set(struct cdns_mhdp8501_device *mhdp, -+ const struct drm_display_mode *mode) -+{ -+ union phy_configure_opts phy_cfg; -+ int ret; -+ -+ cdns_dp_pixel_clk_reset(mhdp); -+ -+ /* Get DP Caps */ -+ ret = drm_dp_dpcd_read(&mhdp->dp.aux, DP_DPCD_REV, mhdp->dp.dpcd, -+ DP_RECEIVER_CAP_SIZE); -+ if (ret < 0) { -+ dev_err(mhdp->dev, "Failed to get caps %d\n", ret); -+ return; -+ } -+ -+ mhdp->dp.rate = drm_dp_max_link_rate(mhdp->dp.dpcd); -+ mhdp->dp.num_lanes = drm_dp_max_lane_count(mhdp->dp.dpcd); -+ -+ /* check the max link rate */ -+ if (mhdp->dp.rate > CDNS_DP_MAX_LINK_RATE) -+ mhdp->dp.rate = CDNS_DP_MAX_LINK_RATE; -+ -+ phy_cfg.dp.lanes = mhdp->dp.num_lanes; -+ phy_cfg.dp.link_rate = mhdp->dp.rate; -+ phy_cfg.dp.set_lanes = false; -+ phy_cfg.dp.set_rate = false; -+ phy_cfg.dp.set_voltages = false; -+ -+ ret = phy_configure(mhdp->phy, &phy_cfg); -+ if (ret) { -+ dev_err(mhdp->dev, "%s: phy_configure() failed: %d\n", -+ __func__, ret); -+ return; -+ } -+ -+ /* Video off */ -+ ret = cdns_dp_set_video_status(mhdp, CONTROL_VIDEO_IDLE); -+ if (ret) { -+ dev_err(mhdp->dev, "Failed to valid video %d\n", ret); -+ return; -+ } -+ -+ /* Line swapping */ -+ cdns_mhdp_reg_write(&mhdp->base, LANES_CONFIG, 0x00400000 | mhdp->lane_mapping); -+ -+ /* Set DP host capability */ -+ ret = cdns_dp_set_host_cap(mhdp); -+ if (ret) { -+ dev_err(mhdp->dev, "Failed to set host cap %d\n", ret); -+ return; -+ } -+ -+ ret = cdns_mhdp_reg_write(&mhdp->base, DP_AUX_SWAP_INVERSION_CONTROL, -+ AUX_HOST_INVERT); -+ if (ret) { -+ dev_err(mhdp->dev, "Failed to set host invert %d\n", ret); -+ return; -+ } -+ -+ ret = cdns_dp_config_video(mhdp, mode); -+ if (ret) -+ dev_err(mhdp->dev, "Failed to config video %d\n", ret); -+} -+ -+static bool -+cdns_dp_needs_link_retrain(struct cdns_mhdp8501_device *mhdp) -+{ -+ u8 link_status[DP_LINK_STATUS_SIZE]; -+ -+ if (drm_dp_dpcd_read_phy_link_status(&mhdp->dp.aux, DP_PHY_DPRX, -+ link_status) < 0) -+ return false; -+ -+ /* Retrain if link not ok */ -+ return !drm_dp_channel_eq_ok(link_status, mhdp->dp.num_lanes); -+} -+ -+void cdns_dp_check_link_state(struct cdns_mhdp8501_device *mhdp) -+{ -+ struct drm_connector *connector = mhdp->curr_conn; -+ const struct drm_edid *drm_edid; -+ struct drm_connector_state *conn_state; -+ struct drm_crtc_state *crtc_state; -+ struct drm_crtc *crtc; -+ -+ if (!connector) -+ return; -+ -+ drm_edid = drm_edid_read_custom(connector, cdns_dp_get_edid_block, mhdp); -+ drm_edid_connector_update(connector, drm_edid); -+ -+ if (!drm_edid) -+ return; -+ -+ drm_edid_free(drm_edid); -+ -+ conn_state = connector->state; -+ crtc = conn_state->crtc; -+ if (!crtc) -+ return; -+ -+ crtc_state = crtc->state; -+ if (!crtc_state->active) -+ return; -+ -+ if (!cdns_dp_needs_link_retrain(mhdp)) -+ return; -+ -+ /* DP link retrain */ -+ if (cdns_dp_train_link(mhdp)) -+ dev_err(mhdp->dev, "Failed link train\n"); -+} -+ -+static int cdns_dp_bridge_attach(struct drm_bridge *bridge, -+ enum drm_bridge_attach_flags flags) -+{ -+ struct cdns_mhdp8501_device *mhdp = bridge->driver_private; -+ -+ if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) { -+ dev_err(mhdp->dev, "do not support creating a drm_connector\n"); -+ return -EINVAL; -+ } -+ -+ mhdp->dp.aux.drm_dev = bridge->dev; -+ -+ return drm_dp_aux_register(&mhdp->dp.aux); -+} -+ -+static enum drm_mode_status -+cdns_dp_bridge_mode_valid(struct drm_bridge *bridge, -+ const struct drm_display_info *info, -+ const struct drm_display_mode *mode) -+{ -+ enum drm_mode_status mode_status = MODE_OK; -+ -+ /* We don't support double-clocked modes */ -+ if (mode->flags & DRM_MODE_FLAG_DBLCLK || -+ mode->flags & DRM_MODE_FLAG_INTERLACE) -+ return MODE_BAD; -+ -+ /* MAX support pixel clock rate 594MHz */ -+ if (mode->clock > 594000) -+ return MODE_CLOCK_HIGH; -+ -+ if (mode->hdisplay > 3840) -+ return MODE_BAD_HVALUE; -+ -+ if (mode->vdisplay > 2160) -+ return MODE_BAD_VVALUE; -+ -+ return mode_status; -+} -+ -+static enum drm_connector_status -+cdns_dp_bridge_detect(struct drm_bridge *bridge) -+{ -+ struct cdns_mhdp8501_device *mhdp = bridge->driver_private; -+ -+ return cdns_mhdp8501_detect(mhdp); -+} -+ -+static const struct drm_edid -+*cdns_dp_bridge_edid_read(struct drm_bridge *bridge, -+ struct drm_connector *connector) -+{ -+ struct cdns_mhdp8501_device *mhdp = bridge->driver_private; -+ -+ return drm_edid_read_custom(connector, cdns_dp_get_edid_block, mhdp); -+} -+ -+static void cdns_dp_bridge_atomic_disable(struct drm_bridge *bridge, -+ struct drm_bridge_state *old_state) -+{ -+ struct cdns_mhdp8501_device *mhdp = bridge->driver_private; -+ -+ cdns_dp_set_video_status(mhdp, CONTROL_VIDEO_IDLE); -+ mhdp->curr_conn = NULL; -+ -+ phy_power_off(mhdp->phy); -+} -+ -+static void cdns_dp_bridge_atomic_enable(struct drm_bridge *bridge, -+ struct drm_bridge_state *old_state) -+{ -+ struct cdns_mhdp8501_device *mhdp = bridge->driver_private; -+ struct drm_atomic_state *state = old_state->base.state; -+ struct drm_connector *connector; -+ struct video_info *video = &mhdp->video_info; -+ struct drm_crtc_state *crtc_state; -+ struct drm_connector_state *conn_state; -+ int ret; -+ -+ connector = drm_atomic_get_new_connector_for_encoder(state, -+ bridge->encoder); -+ if (WARN_ON(!connector)) -+ return; -+ -+ mhdp->curr_conn = connector; -+ -+ conn_state = drm_atomic_get_new_connector_state(state, connector); -+ if (WARN_ON(!conn_state)) -+ return; -+ -+ crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc); -+ if (WARN_ON(!crtc_state)) -+ return; -+ -+ switch (connector->display_info.bpc) { -+ case 10: -+ video->bpc = 10; -+ break; -+ case 6: -+ video->bpc = 6; -+ break; -+ default: -+ video->bpc = 8; -+ break; -+ } -+ -+ /* The only currently supported format */ -+ video->color_fmt = DRM_COLOR_FORMAT_RGB444; -+ -+ cdns_dp_mode_set(mhdp, &crtc_state->adjusted_mode); -+ -+ /* Power up PHY before link training */ -+ phy_power_on(mhdp->phy); -+ -+ /* Link training */ -+ ret = cdns_dp_train_link(mhdp); -+ if (ret) { -+ dev_err(mhdp->dev, "Failed link train %d\n", ret); -+ return; -+ } -+ -+ ret = cdns_dp_set_video_status(mhdp, CONTROL_VIDEO_VALID); -+ if (ret) { -+ dev_err(mhdp->dev, "Failed to valid video %d\n", ret); -+ return; -+ } -+} -+ -+const struct drm_bridge_funcs cdns_dp_bridge_funcs = { -+ .attach = cdns_dp_bridge_attach, -+ .detect = cdns_dp_bridge_detect, -+ .edid_read = cdns_dp_bridge_edid_read, -+ .mode_valid = cdns_dp_bridge_mode_valid, -+ .atomic_enable = cdns_dp_bridge_atomic_enable, -+ .atomic_disable = cdns_dp_bridge_atomic_disable, -+ .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, -+ .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, -+ .atomic_reset = drm_atomic_helper_bridge_reset, -+}; -diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c -new file mode 100644 -index 0000000000000..f7cafc153a58e ---- /dev/null -+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c -@@ -0,0 +1,764 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Cadence MHDP8501 HDMI bridge driver -+ * -+ * Copyright (C) 2019-2024 NXP Semiconductor, Inc. -+ * -+ */ -+#include <drm/display/drm_hdmi_helper.h> -+#include <drm/display/drm_hdmi_state_helper.h> -+#include <drm/display/drm_scdc_helper.h> -+#include <drm/drm_atomic_helper.h> -+#include <drm/drm_edid.h> -+#include <drm/drm_print.h> -+#include <linux/phy/phy.h> -+#include <linux/phy/phy-hdmi.h> -+ -+#include "cdns-mhdp8501-core.h" -+ -+/** -+ * cdns_hdmi_config_infoframe() - fill the HDMI infoframe -+ * @mhdp: phandle to mhdp device. -+ * @entry_id: The packet memory address in which the data is written. -+ * @len: length of infoframe. -+ * @buf: point to InfoFrame Packet. -+ * @type: Packet Type of InfoFrame in HDMI Specification. -+ * -+ */ -+ -+static void cdns_hdmi_clear_infoframe(struct cdns_mhdp8501_device *mhdp, -+ u8 entry_id, u8 type) -+{ -+ u32 val; -+ -+ /* invalidate entry */ -+ val = F_ACTIVE_IDLE_TYPE(1) | F_PKT_ALLOC_ADDRESS(entry_id) | -+ F_PACKET_TYPE(type); -+ writel(val, mhdp->regs + SOURCE_PIF_PKT_ALLOC_REG); -+ writel(F_PKT_ALLOC_WR_EN(1), mhdp->regs + SOURCE_PIF_PKT_ALLOC_WR_EN); -+} -+ -+static void cdns_hdmi_config_infoframe(struct cdns_mhdp8501_device *mhdp, -+ u8 entry_id, u8 len, -+ const u8 *buf, u8 type) -+{ -+ u8 packet[32], packet_len = 32; -+ u32 packet32, len32; -+ u32 val, i; -+ -+ /* -+ * only support 32 bytes now -+ * packet[0] = 0 -+ * packet[1-3] = HB[0-2] InfoFrame Packet Header -+ * packet[4-31 = PB[0-27] InfoFrame Packet Contents -+ */ -+ if (len >= (packet_len - 1)) -+ return; -+ packet[0] = 0; -+ memcpy(packet + 1, buf, len); -+ -+ cdns_hdmi_clear_infoframe(mhdp, entry_id, type); -+ -+ /* flush fifo 1 */ -+ writel(F_FIFO1_FLUSH(1), mhdp->regs + SOURCE_PIF_FIFO1_FLUSH); -+ -+ /* write packet into memory */ -+ len32 = packet_len / 4; -+ for (i = 0; i < len32; i++) { -+ packet32 = get_unaligned_le32(packet + 4 * i); -+ writel(F_DATA_WR(packet32), mhdp->regs + SOURCE_PIF_DATA_WR); -+ } -+ -+ /* write entry id */ -+ writel(F_WR_ADDR(entry_id), mhdp->regs + SOURCE_PIF_WR_ADDR); -+ -+ /* write request */ -+ writel(F_HOST_WR(1), mhdp->regs + SOURCE_PIF_WR_REQ); -+ -+ /* update entry */ -+ val = F_ACTIVE_IDLE_TYPE(1) | F_TYPE_VALID(1) | -+ F_PACKET_TYPE(type) | F_PKT_ALLOC_ADDRESS(entry_id); -+ writel(val, mhdp->regs + SOURCE_PIF_PKT_ALLOC_REG); -+ -+ writel(F_PKT_ALLOC_WR_EN(1), mhdp->regs + SOURCE_PIF_PKT_ALLOC_WR_EN); -+} -+ -+static int cdns_hdmi_get_edid_block(void *data, u8 *edid, -+ u32 block, size_t length) -+{ -+ struct cdns_mhdp8501_device *mhdp = data; -+ u8 msg[2], reg[5], i; -+ int ret; -+ -+ for (i = 0; i < 4; i++) { -+ msg[0] = block / 2; -+ msg[1] = block % 2; -+ -+ ret = cdns_mhdp_mailbox_send_recv_multi(&mhdp->base, -+ MB_MODULE_ID_HDMI_TX, -+ HDMI_TX_EDID, -+ sizeof(msg), msg, -+ HDMI_TX_EDID, -+ sizeof(reg), reg, -+ length, edid); -+ -+ if (ret) -+ continue; -+ -+ if ((reg[3] << 8 | reg[4]) == length) -+ break; -+ } -+ -+ if (ret) -+ dev_err(mhdp->dev, "get block[%d] edid failed: %d\n", block, ret); -+ return ret; -+} -+ -+static int cdns_hdmi_set_hdmi_mode_type(struct cdns_mhdp8501_device *mhdp) -+{ -+ struct drm_connector_state *conn_state = mhdp->curr_conn->state; -+ u32 protocol = mhdp->hdmi.hdmi_type; -+ u32 val; -+ -+ if (protocol == MODE_HDMI_2_0 && -+ conn_state->hdmi.tmds_char_rate >= 340000000) { -+ cdns_mhdp_reg_write(&mhdp->base, HDTX_CLOCK_REG_0, 0); -+ cdns_mhdp_reg_write(&mhdp->base, HDTX_CLOCK_REG_1, 0xFFFFF); -+ } -+ -+ cdns_mhdp_reg_read(&mhdp->base, HDTX_CONTROLLER, &val); -+ -+ /* set HDMI mode and preemble mode data enable */ -+ val |= F_HDMI_MODE(protocol) | F_HDMI2_PREAMBLE_EN(1) | -+ F_HDMI2_CTRL_IL_MODE(1); -+ return cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER, val); -+} -+ -+static int cdns_hdmi_ctrl_init(struct cdns_mhdp8501_device *mhdp) -+{ -+ u32 val; -+ int ret; -+ -+ /* Set PHY to HDMI data */ -+ ret = cdns_mhdp_reg_write(&mhdp->base, PHY_DATA_SEL, F_SOURCE_PHY_MHDP_SEL(1)); -+ if (ret < 0) -+ return ret; -+ -+ ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_HPD, -+ F_HPD_VALID_WIDTH(4) | F_HPD_GLITCH_WIDTH(0)); -+ if (ret < 0) -+ return ret; -+ -+ /* open CARS */ -+ ret = cdns_mhdp_reg_write(&mhdp->base, SOURCE_PHY_CAR, 0xF); -+ if (ret < 0) -+ return ret; -+ ret = cdns_mhdp_reg_write(&mhdp->base, SOURCE_HDTX_CAR, 0xFF); -+ if (ret < 0) -+ return ret; -+ ret = cdns_mhdp_reg_write(&mhdp->base, SOURCE_PKT_CAR, 0xF); -+ if (ret < 0) -+ return ret; -+ ret = cdns_mhdp_reg_write(&mhdp->base, SOURCE_AIF_CAR, 0xF); -+ if (ret < 0) -+ return ret; -+ ret = cdns_mhdp_reg_write(&mhdp->base, SOURCE_CIPHER_CAR, 0xF); -+ if (ret < 0) -+ return ret; -+ ret = cdns_mhdp_reg_write(&mhdp->base, SOURCE_CRYPTO_CAR, 0xF); -+ if (ret < 0) -+ return ret; -+ ret = cdns_mhdp_reg_write(&mhdp->base, SOURCE_CEC_CAR, 3); -+ if (ret < 0) -+ return ret; -+ -+ ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_CLOCK_REG_0, 0x7c1f); -+ if (ret < 0) -+ return ret; -+ ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_CLOCK_REG_1, 0x7c1f); -+ if (ret < 0) -+ return ret; -+ -+ /* init HDMI Controller */ -+ val = F_BCH_EN(1) | F_PIC_3D(0xF) | F_CLEAR_AVMUTE(1); -+ ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER, val); -+ if (ret < 0) -+ return ret; -+ -+ return cdns_hdmi_set_hdmi_mode_type(mhdp); -+} -+ -+static int cdns_hdmi_mode_config(struct cdns_mhdp8501_device *mhdp, -+ struct drm_display_mode *mode, -+ struct drm_connector_hdmi_state *hdmi) -+{ -+ u32 vsync_lines = mode->vsync_end - mode->vsync_start; -+ u32 eof_lines = mode->vsync_start - mode->vdisplay; -+ u32 sof_lines = mode->vtotal - mode->vsync_end; -+ u32 hblank = mode->htotal - mode->hdisplay; -+ u32 hactive = mode->hdisplay; -+ u32 vblank = mode->vtotal - mode->vdisplay; -+ u32 vactive = mode->vdisplay; -+ u32 hfront = mode->hsync_start - mode->hdisplay; -+ u32 hback = mode->htotal - mode->hsync_end; -+ u32 vfront = eof_lines; -+ u32 hsync = hblank - hfront - hback; -+ u32 vsync = vsync_lines; -+ u32 vback = sof_lines; -+ u32 v_h_polarity = ((mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : 1) + -+ ((mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : 2); -+ int ret; -+ u32 val; -+ -+ ret = cdns_mhdp_reg_write(&mhdp->base, SCHEDULER_H_SIZE, (hactive << 16) + hblank); -+ if (ret < 0) -+ return ret; -+ -+ ret = cdns_mhdp_reg_write(&mhdp->base, SCHEDULER_V_SIZE, (vactive << 16) + vblank); -+ if (ret < 0) -+ return ret; -+ -+ ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_SIGNAL_FRONT_WIDTH, (vfront << 16) + hfront); -+ if (ret < 0) -+ return ret; -+ -+ ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_SIGNAL_SYNC_WIDTH, (vsync << 16) + hsync); -+ if (ret < 0) -+ return ret; -+ -+ ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_SIGNAL_BACK_WIDTH, (vback << 16) + hback); -+ if (ret < 0) -+ return ret; -+ -+ ret = cdns_mhdp_reg_write(&mhdp->base, HSYNC2VSYNC_POL_CTRL, v_h_polarity); -+ if (ret < 0) -+ return ret; -+ -+ /* Reset Data Enable */ -+ cdns_mhdp_reg_read(&mhdp->base, HDTX_CONTROLLER, &val); -+ val &= ~F_DATA_EN(1); -+ ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER, val); -+ if (ret < 0) -+ return ret; -+ -+ /* Set bpc */ -+ val &= ~F_VIF_DATA_WIDTH(3); -+ switch (hdmi->output_bpc) { -+ case 10: -+ val |= F_VIF_DATA_WIDTH(1); -+ break; -+ case 12: -+ val |= F_VIF_DATA_WIDTH(2); -+ break; -+ case 16: -+ val |= F_VIF_DATA_WIDTH(3); -+ break; -+ case 8: -+ default: -+ val |= F_VIF_DATA_WIDTH(0); -+ break; -+ } -+ -+ /* select color encoding */ -+ val &= ~F_HDMI_ENCODING(3); -+ switch (hdmi->output_format) { -+ case HDMI_COLORSPACE_YUV444: -+ val |= F_HDMI_ENCODING(2); -+ break; -+ case HDMI_COLORSPACE_YUV422: -+ val |= F_HDMI_ENCODING(1); -+ break; -+ case HDMI_COLORSPACE_YUV420: -+ val |= F_HDMI_ENCODING(3); -+ break; -+ case HDMI_COLORSPACE_RGB: -+ default: -+ val |= F_HDMI_ENCODING(0); -+ break; -+ } -+ -+ ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER, val); -+ if (ret < 0) -+ return ret; -+ -+ /* set data enable */ -+ val |= F_DATA_EN(1); -+ return cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER, val); -+} -+ -+static int cdns_hdmi_disable_gcp(struct cdns_mhdp8501_device *mhdp) -+{ -+ u32 val; -+ -+ cdns_mhdp_reg_read(&mhdp->base, HDTX_CONTROLLER, &val); -+ val &= ~F_GCP_EN(1); -+ -+ return cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER, val); -+} -+ -+static int cdns_hdmi_enable_gcp(struct cdns_mhdp8501_device *mhdp) -+{ -+ u32 val; -+ -+ cdns_mhdp_reg_read(&mhdp->base, HDTX_CONTROLLER, &val); -+ val |= F_GCP_EN(1); -+ -+ return cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER, val); -+} -+ -+#define HDMI_14_MAX_TMDS_CLK (340 * 1000 * 1000) -+static void cdns_hdmi_sink_config(struct cdns_mhdp8501_device *mhdp, -+ unsigned long long tmds_char_rate) -+{ -+ struct drm_connector *connector = mhdp->curr_conn; -+ struct drm_display_info *display = &connector->display_info; -+ struct drm_scdc *scdc = &display->hdmi.scdc; -+ bool hdmi_scrambling = false; -+ bool hdmi_high_tmds_clock_ratio = false; -+ -+ /* check sink type (HDMI or DVI) */ -+ if (!display->is_hdmi) { -+ mhdp->hdmi.hdmi_type = MODE_DVI; -+ return; -+ } -+ -+ /* Default work in HDMI1.4 */ -+ mhdp->hdmi.hdmi_type = MODE_HDMI_1_4; -+ -+ /* check sink support SCDC or not */ -+ if (!scdc->supported) { -+ dev_dbg(mhdp->dev, "Sink Not Support SCDC\n"); -+ return; -+ } -+ -+ if (tmds_char_rate > HDMI_14_MAX_TMDS_CLK) { -+ hdmi_scrambling = true; -+ hdmi_high_tmds_clock_ratio = true; -+ mhdp->hdmi.hdmi_type = MODE_HDMI_2_0; -+ } else if (scdc->scrambling.low_rates) { -+ hdmi_scrambling = true; -+ mhdp->hdmi.hdmi_type = MODE_HDMI_2_0; -+ } -+ -+ /* Set TMDS bit clock ratio to 1/40 or 1/10, and enable/disable scrambling */ -+ drm_scdc_set_high_tmds_clock_ratio(connector, hdmi_high_tmds_clock_ratio); -+ drm_scdc_set_scrambling(connector, hdmi_scrambling); -+} -+ -+static int cdns_hdmi_bridge_attach(struct drm_bridge *bridge, -+ enum drm_bridge_attach_flags flags) -+{ -+ struct cdns_mhdp8501_device *mhdp = bridge->driver_private; -+ -+ if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) { -+ dev_err(mhdp->dev, "do not support creating a drm_connector\n"); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int reset_pipe(struct drm_crtc *crtc) -+{ -+ struct drm_atomic_state *state; -+ struct drm_crtc_state *crtc_state; -+ struct drm_modeset_acquire_ctx ctx; -+ int ret; -+ -+ state = drm_atomic_state_alloc(crtc->dev); -+ if (!state) -+ return -ENOMEM; -+ -+ drm_modeset_acquire_init(&ctx, 0); -+ -+ state->acquire_ctx = &ctx; -+ -+ crtc_state = drm_atomic_get_crtc_state(state, crtc); -+ if (IS_ERR(crtc_state)) { -+ ret = PTR_ERR(crtc_state); -+ goto out; -+ } -+ -+ crtc_state->connectors_changed = true; -+ -+ ret = drm_atomic_commit(state); -+out: -+ drm_atomic_state_put(state); -+ drm_modeset_drop_locks(&ctx); -+ drm_modeset_acquire_fini(&ctx); -+ -+ return ret; -+} -+ -+void cdns_hdmi_reset_link(struct cdns_mhdp8501_device *mhdp) -+{ -+ struct drm_connector *connector = mhdp->curr_conn; -+ const struct drm_edid *drm_edid; -+ struct drm_connector_state *conn_state; -+ struct drm_crtc_state *crtc_state; -+ struct drm_crtc *crtc; -+ -+ if (!connector) -+ return; -+ -+ drm_edid = drm_edid_read_custom(connector, cdns_hdmi_get_edid_block, mhdp); -+ drm_edid_connector_update(connector, drm_edid); -+ -+ if (!drm_edid) -+ return; -+ -+ drm_edid_free(drm_edid); -+ -+ conn_state = connector->state; -+ crtc = conn_state->crtc; -+ if (!crtc) -+ return; -+ -+ crtc_state = crtc->state; -+ if (!crtc_state->active) -+ return; -+ -+ /* -+ * HDMI 2.0 says that one should not send scrambled data -+ * prior to configuring the sink scrambling, and that -+ * TMDS clock/data transmission should be suspended when -+ * changing the TMDS clock rate in the sink. So let's -+ * just do a full modeset here, even though some sinks -+ * would be perfectly happy if were to just reconfigure -+ * the SCDC settings on the fly. -+ */ -+ reset_pipe(crtc); -+} -+ -+static int cdns_hdmi_i2c_write(struct cdns_mhdp8501_device *mhdp, -+ struct i2c_msg *msgs) -+{ -+ u8 msg[5], reg[5]; -+ int ret; -+ -+ msg[0] = msgs->addr; -+ msg[1] = msgs->buf[0]; -+ msg[2] = 0; -+ msg[3] = 1; -+ msg[4] = msgs->buf[1]; -+ -+ ret = cdns_mhdp_mailbox_send_recv(&mhdp->base, -+ MB_MODULE_ID_HDMI_TX, HDMI_TX_WRITE, -+ sizeof(msg), msg, sizeof(reg), reg); -+ if (ret) { -+ dev_err(mhdp->dev, "I2C write failed: %d\n", ret); -+ return ret; -+ } -+ -+ if (reg[0] != 0) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static int cdns_hdmi_i2c_read(struct cdns_mhdp8501_device *mhdp, -+ struct i2c_msg *msgs, int num) -+{ -+ u8 msg[4], reg[5]; -+ u8 addr, offset, *buf, len; -+ int ret, i; -+ -+ for (i = 0; i < num; i++) { -+ if (msgs[i].flags & I2C_M_RD) { -+ addr = msgs[i].addr; -+ buf = msgs[i].buf; -+ len = msgs[i].len; -+ } else { -+ offset = msgs[i].buf[0]; -+ } -+ } -+ -+ msg[0] = addr; -+ msg[1] = offset; -+ put_unaligned_be16(len, msg + 2); -+ -+ ret = cdns_mhdp_mailbox_send_recv_multi(&mhdp->base, -+ MB_MODULE_ID_HDMI_TX, HDMI_TX_READ, -+ sizeof(msg), msg, -+ HDMI_TX_READ, -+ sizeof(reg), reg, -+ len, buf); -+ if (ret) { -+ dev_err(mhdp->dev, "I2c Read failed: %d\n", ret); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+#define SCDC_I2C_SLAVE_ADDRESS 0x54 -+static int cdns_hdmi_i2c_xfer(struct i2c_adapter *adap, -+ struct i2c_msg *msgs, int num) -+{ -+ struct cdns_mhdp8501_device *mhdp = i2c_get_adapdata(adap); -+ struct cdns_hdmi_i2c *i2c = mhdp->hdmi.i2c; -+ int i, ret = 0; -+ -+ /* Only support SCDC I2C Read/Write */ -+ for (i = 0; i < num; i++) { -+ if (msgs[i].addr != SCDC_I2C_SLAVE_ADDRESS) { -+ dev_err(mhdp->dev, "ADDR=%0x is not supported\n", msgs[i].addr); -+ return -EINVAL; -+ } -+ } -+ -+ mutex_lock(&i2c->lock); -+ -+ if (num == 1) -+ ret = cdns_hdmi_i2c_write(mhdp, msgs); -+ else -+ ret = cdns_hdmi_i2c_read(mhdp, msgs, num); -+ -+ if (!ret) -+ ret = num; -+ -+ mutex_unlock(&i2c->lock); -+ -+ return ret; -+} -+ -+static u32 cdns_hdmi_i2c_func(struct i2c_adapter *adapter) -+{ -+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; -+} -+ -+static const struct i2c_algorithm cdns_hdmi_algorithm = { -+ .master_xfer = cdns_hdmi_i2c_xfer, -+ .functionality = cdns_hdmi_i2c_func, -+}; -+ -+struct i2c_adapter *cdns_hdmi_i2c_adapter(struct cdns_mhdp8501_device *mhdp) -+{ -+ struct i2c_adapter *adap; -+ struct cdns_hdmi_i2c *i2c; -+ int ret; -+ -+ i2c = devm_kzalloc(mhdp->dev, sizeof(*i2c), GFP_KERNEL); -+ if (!i2c) -+ return ERR_PTR(-ENOMEM); -+ -+ mutex_init(&i2c->lock); -+ -+ adap = &i2c->adap; -+ adap->owner = THIS_MODULE; -+ adap->dev.parent = mhdp->dev; -+ adap->algo = &cdns_hdmi_algorithm; -+ strscpy(adap->name, "MHDP HDMI", sizeof(adap->name)); -+ i2c_set_adapdata(adap, mhdp); -+ -+ ret = i2c_add_adapter(adap); -+ if (ret) { -+ dev_warn(mhdp->dev, "cannot add %s I2C adapter\n", adap->name); -+ devm_kfree(mhdp->dev, i2c); -+ return ERR_PTR(ret); -+ } -+ -+ mhdp->hdmi.i2c = i2c; -+ -+ return adap; -+} -+ -+static enum drm_mode_status -+cdns_hdmi_tmds_char_rate_valid(const struct drm_bridge *bridge, -+ const struct drm_display_mode *mode, -+ unsigned long long tmds_rate) -+{ -+ struct cdns_mhdp8501_device *mhdp = bridge->driver_private; -+ union phy_configure_opts phy_cfg; -+ int ret; -+ -+ phy_cfg.hdmi.tmds_char_rate = tmds_rate; -+ -+ ret = phy_validate(mhdp->phy, PHY_MODE_HDMI, 0, &phy_cfg); -+ if (ret < 0) -+ return MODE_CLOCK_RANGE; -+ -+ return MODE_OK; -+} -+ -+static enum drm_mode_status -+cdns_hdmi_bridge_mode_valid(struct drm_bridge *bridge, -+ const struct drm_display_info *info, -+ const struct drm_display_mode *mode) -+{ -+ /* We don't support double-clocked and Interlaced modes */ -+ if (mode->flags & DRM_MODE_FLAG_DBLCLK || -+ mode->flags & DRM_MODE_FLAG_INTERLACE) -+ return MODE_BAD; -+ -+ if (mode->hdisplay > 3840) -+ return MODE_BAD_HVALUE; -+ -+ if (mode->vdisplay > 2160) -+ return MODE_BAD_VVALUE; -+ -+ return MODE_OK; -+} -+ -+static enum drm_connector_status -+cdns_hdmi_bridge_detect(struct drm_bridge *bridge) -+{ -+ struct cdns_mhdp8501_device *mhdp = bridge->driver_private; -+ -+ return cdns_mhdp8501_detect(mhdp); -+} -+ -+static const struct drm_edid -+*cdns_hdmi_bridge_edid_read(struct drm_bridge *bridge, -+ struct drm_connector *connector) -+{ -+ struct cdns_mhdp8501_device *mhdp = bridge->driver_private; -+ -+ return drm_edid_read_custom(connector, cdns_hdmi_get_edid_block, mhdp); -+} -+ -+static void cdns_hdmi_bridge_atomic_disable(struct drm_bridge *bridge, -+ struct drm_bridge_state *old_state) -+{ -+ struct cdns_mhdp8501_device *mhdp = bridge->driver_private; -+ -+ mhdp->curr_conn = NULL; -+ -+ phy_power_off(mhdp->phy); -+} -+ -+static void cdns_hdmi_bridge_atomic_enable(struct drm_bridge *bridge, -+ struct drm_bridge_state *old_state) -+{ -+ struct cdns_mhdp8501_device *mhdp = bridge->driver_private; -+ struct drm_atomic_state *state = old_state->base.state; -+ struct drm_connector *connector; -+ struct drm_crtc_state *crtc_state; -+ struct drm_connector_state *conn_state; -+ struct drm_connector_hdmi_state *hdmi; -+ union phy_configure_opts phy_cfg; -+ int ret; -+ -+ connector = drm_atomic_get_new_connector_for_encoder(state, -+ bridge->encoder); -+ if (WARN_ON(!connector)) -+ return; -+ -+ mhdp->curr_conn = connector; -+ -+ conn_state = drm_atomic_get_new_connector_state(state, connector); -+ if (WARN_ON(!conn_state)) -+ return; -+ -+ crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc); -+ if (WARN_ON(!crtc_state)) -+ return; -+ -+ drm_atomic_helper_connector_hdmi_update_infoframes(connector, state); -+ -+ /* Line swapping */ -+ cdns_mhdp_reg_write(&mhdp->base, LANES_CONFIG, 0x00400000 | mhdp->lane_mapping); -+ -+ hdmi = &conn_state->hdmi; -+ if (WARN_ON(!hdmi)) -+ return; -+ -+ phy_cfg.hdmi.tmds_char_rate = hdmi->tmds_char_rate; -+ ret = phy_configure(mhdp->phy, &phy_cfg); -+ if (ret) { -+ dev_err(mhdp->dev, "%s: phy_configure() failed: %d\n", -+ __func__, ret); -+ return; -+ } -+ -+ phy_power_on(mhdp->phy); -+ -+ cdns_hdmi_sink_config(mhdp, hdmi->tmds_char_rate); -+ -+ ret = cdns_hdmi_ctrl_init(mhdp); -+ if (ret < 0) { -+ dev_err(mhdp->dev, "hdmi ctrl init failed = %d\n", ret); -+ return; -+ } -+ -+ /* Config GCP */ -+ if (hdmi->output_bpc == 8) -+ cdns_hdmi_disable_gcp(mhdp); -+ else -+ cdns_hdmi_enable_gcp(mhdp); -+ -+ ret = cdns_hdmi_mode_config(mhdp, &crtc_state->adjusted_mode, hdmi); -+ if (ret < 0) { -+ dev_err(mhdp->dev, "CDN_API_HDMITX_SetVic_blocking ret = %d\n", ret); -+ return; -+ } -+} -+ -+static int cdns_hdmi_bridge_clear_infoframe(struct drm_bridge *bridge, -+ enum hdmi_infoframe_type type) -+{ -+ struct cdns_mhdp8501_device *mhdp = bridge->driver_private; -+ -+ switch (type) { -+ case HDMI_INFOFRAME_TYPE_AVI: -+ cdns_hdmi_clear_infoframe(mhdp, 0, HDMI_INFOFRAME_TYPE_AVI); -+ break; -+ case HDMI_INFOFRAME_TYPE_SPD: -+ cdns_hdmi_clear_infoframe(mhdp, 1, HDMI_INFOFRAME_TYPE_SPD); -+ break; -+ case HDMI_INFOFRAME_TYPE_VENDOR: -+ cdns_hdmi_clear_infoframe(mhdp, 2, HDMI_INFOFRAME_TYPE_VENDOR); -+ break; -+ default: -+ dev_dbg(mhdp->dev, "Unsupported infoframe type %x\n", type); -+ } -+ -+ return 0; -+} -+ -+static int cdns_hdmi_bridge_write_infoframe(struct drm_bridge *bridge, -+ enum hdmi_infoframe_type type, -+ const u8 *buffer, size_t len) -+{ -+ struct cdns_mhdp8501_device *mhdp = bridge->driver_private; -+ -+ switch (type) { -+ case HDMI_INFOFRAME_TYPE_AVI: -+ cdns_hdmi_config_infoframe(mhdp, 0, len, buffer, HDMI_INFOFRAME_TYPE_AVI); -+ break; -+ case HDMI_INFOFRAME_TYPE_SPD: -+ cdns_hdmi_config_infoframe(mhdp, 1, len, buffer, HDMI_INFOFRAME_TYPE_SPD); -+ break; -+ case HDMI_INFOFRAME_TYPE_VENDOR: -+ cdns_hdmi_config_infoframe(mhdp, 2, len, buffer, HDMI_INFOFRAME_TYPE_VENDOR); -+ break; -+ default: -+ dev_dbg(mhdp->dev, "Unsupported infoframe type %x\n", type); -+ } -+ -+ return 0; -+} -+ -+static int cdns_hdmi_bridge_atomic_check(struct drm_bridge *bridge, -+ struct drm_bridge_state *bridge_state, -+ struct drm_crtc_state *crtc_state, -+ struct drm_connector_state *conn_state) -+{ -+ return drm_atomic_helper_connector_hdmi_check(conn_state->connector, conn_state->state); -+} -+ -+const struct drm_bridge_funcs cdns_hdmi_bridge_funcs = { -+ .attach = cdns_hdmi_bridge_attach, -+ .detect = cdns_hdmi_bridge_detect, -+ .edid_read = cdns_hdmi_bridge_edid_read, -+ .mode_valid = cdns_hdmi_bridge_mode_valid, -+ .atomic_enable = cdns_hdmi_bridge_atomic_enable, -+ .atomic_disable = cdns_hdmi_bridge_atomic_disable, -+ .atomic_check = cdns_hdmi_bridge_atomic_check, -+ .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, -+ .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, -+ .atomic_reset = drm_atomic_helper_bridge_reset, -+ .hdmi_clear_infoframe = cdns_hdmi_bridge_clear_infoframe, -+ .hdmi_write_infoframe = cdns_hdmi_bridge_write_infoframe, -+ .hdmi_tmds_char_rate_valid = cdns_hdmi_tmds_char_rate_valid, -+}; --- -2.34.1 - -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH v19 5/8] dt-bindings: phy: Add Freescale iMX8MQ DP and HDMI - PHY -From: Sandor Yu <Sandor.yu@nxp.com> -Date: Tue, 26 Nov 2024 22:11:50 +0800 -Message-Id: <54ee86767e5b6c7320b9b2053e404e615c290287.1732627815.git.Sandor.yu@nxp.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -Add bindings for Freescale iMX8MQ DP and HDMI PHY. - -Signed-off-by: Sandor Yu <Sandor.yu@nxp.com> -Reviewed-by: Rob Herring <robh@kernel.org> ---- -v9->v18: - *No change. - - .../bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml | 51 +++++++++++++++++++ - 1 file changed, 51 insertions(+) - create mode 100644 Documentation/devicetree/bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml - -diff --git a/Documentation/devicetree/bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml b/Documentation/devicetree/bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml -new file mode 100644 -index 0000000000000..c17a645e71bad ---- /dev/null -+++ b/Documentation/devicetree/bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml -@@ -0,0 +1,51 @@ -+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/phy/fsl,imx8mq-dp-hdmi-phy.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: Cadence HDP-TX DP/HDMI PHY for Freescale i.MX8MQ SoC -+ -+maintainers: -+ - Sandor Yu <sandor.yu@nxp.com> -+ -+properties: -+ compatible: -+ const: fsl,imx8mq-hdptx-phy -+ -+ reg: -+ maxItems: 1 -+ -+ clocks: -+ items: -+ - description: PHY reference clock. -+ - description: APB clock. -+ -+ clock-names: -+ items: -+ - const: ref -+ - const: apb -+ -+ "#phy-cells": -+ const: 0 -+ -+required: -+ - compatible -+ - reg -+ - clocks -+ - clock-names -+ - "#phy-cells" -+ -+additionalProperties: false -+ -+examples: -+ - | -+ #include <dt-bindings/clock/imx8mq-clock.h> -+ #include <dt-bindings/phy/phy.h> -+ dp_phy: phy@32c00000 { -+ compatible = "fsl,imx8mq-hdptx-phy"; -+ reg = <0x32c00000 0x100000>; -+ #phy-cells = <0>; -+ clocks = <&hdmi_phy_27m>, <&clk IMX8MQ_CLK_DISP_APB_ROOT>; -+ clock-names = "ref", "apb"; -+ }; --- -2.34.1 - -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH v19 6/8] phy: freescale: Add DisplayPort/HDMI Combo-PHY - driver for i.MX8MQ -From: Sandor Yu <Sandor.yu@nxp.com> -Date: Tue, 26 Nov 2024 22:11:51 +0800 -Message-Id: <4ef8252825d7a962b440519fb17fdcd5dd817672.1732627815.git.Sandor.yu@nxp.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -Add Cadence HDP-TX DisplayPort and HDMI PHY driver for i.MX8MQ. - -Cadence HDP-TX PHY could be put in either DP mode or -HDMI mode base on the configuration chosen. -DisplayPort or HDMI PHY mode is configured in the driver. - -Signed-off-by: Sandor Yu <Sandor.yu@nxp.com> -Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com> ---- -v18->v19: -- Simplify the PLL tables by removing unused and constant data -- Remove PHY power management, controller driver will handle them. -- Remove enum dp_link_rate -- Introduce read_pll_timeout. -- Update clock management as devm_clk_get_enabled() introduced. -- Remove cdns_hdptx_phy_init() and cdns_hdptx_phy_remove(). - -v17->v18: -- fix build error as code rebase to latest kernel version. - - drivers/phy/freescale/Kconfig | 10 + - drivers/phy/freescale/Makefile | 1 + - drivers/phy/freescale/phy-fsl-imx8mq-hdptx.c | 1237 ++++++++++++++++++ - 3 files changed, 1248 insertions(+) - create mode 100644 drivers/phy/freescale/phy-fsl-imx8mq-hdptx.c - -diff --git a/drivers/phy/freescale/Kconfig b/drivers/phy/freescale/Kconfig -index dcd9acff6d01a..bbd17e9556cc3 100644 ---- a/drivers/phy/freescale/Kconfig -+++ b/drivers/phy/freescale/Kconfig -@@ -35,6 +35,16 @@ config PHY_FSL_IMX8M_PCIE - Enable this to add support for the PCIE PHY as found on - i.MX8M family of SOCs. - -+config PHY_FSL_IMX8MQ_HDPTX -+ tristate "Freescale i.MX8MQ DP/HDMI PHY support" -+ depends on OF && HAS_IOMEM -+ depends on COMMON_CLK -+ depends on CDNS_MHDP_HELPER -+ select GENERIC_PHY -+ help -+ Enable this to support the Cadence HDPTX DP/HDMI PHY driver -+ on i.MX8MQ SOC. -+ - config PHY_FSL_IMX8QM_HSIO - tristate "Freescale i.MX8QM HSIO PHY" - depends on OF && HAS_IOMEM -diff --git a/drivers/phy/freescale/Makefile b/drivers/phy/freescale/Makefile -index 658eac7d0a622..a946b87905498 100644 ---- a/drivers/phy/freescale/Makefile -+++ b/drivers/phy/freescale/Makefile -@@ -1,4 +1,5 @@ - # SPDX-License-Identifier: GPL-2.0-only -+obj-$(CONFIG_PHY_FSL_IMX8MQ_HDPTX) += phy-fsl-imx8mq-hdptx.o - obj-$(CONFIG_PHY_FSL_IMX8MQ_USB) += phy-fsl-imx8mq-usb.o - obj-$(CONFIG_PHY_MIXEL_LVDS_PHY) += phy-fsl-imx8qm-lvds-phy.o - obj-$(CONFIG_PHY_MIXEL_MIPI_DPHY) += phy-fsl-imx8-mipi-dphy.o -diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-hdptx.c b/drivers/phy/freescale/phy-fsl-imx8mq-hdptx.c -new file mode 100644 -index 0000000000000..e99487622d43c ---- /dev/null -+++ b/drivers/phy/freescale/phy-fsl-imx8mq-hdptx.c -@@ -0,0 +1,1237 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Cadence DP/HDMI PHY driver -+ * -+ * Copyright (C) 2022-2024 NXP Semiconductor, Inc. -+ */ -+#include <drm/bridge/cdns-mhdp-helper.h> -+#include <linux/clk.h> -+#include <linux/kernel.h> -+#include <linux/phy/phy.h> -+#include <linux/platform_device.h> -+#include <linux/io.h> -+#include <linux/unaligned.h> -+ -+#define ADDR_PHY_AFE 0x80000 -+ -+/* PHY registers */ -+#define CMN_SSM_BIAS_TMR 0x0022 -+#define CMN_PLLSM0_PLLEN_TMR 0x0029 -+#define CMN_PLLSM0_PLLPRE_TMR 0x002a -+#define CMN_PLLSM0_PLLVREF_TMR 0x002b -+#define CMN_PLLSM0_PLLLOCK_TMR 0x002c -+#define CMN_PLLSM0_USER_DEF_CTRL 0x002f -+#define CMN_PSM_CLK_CTRL 0x0061 -+#define CMN_CDIAG_REFCLK_CTRL 0x0062 -+#define CMN_PLL0_VCOCAL_START 0x0081 -+#define CMN_PLL0_VCOCAL_INIT_TMR 0x0084 -+#define CMN_PLL0_VCOCAL_ITER_TMR 0x0085 -+#define CMN_PLL0_INTDIV 0x0094 -+#define CMN_PLL0_FRACDIV 0x0095 -+#define CMN_PLL0_HIGH_THR 0x0096 -+#define CMN_PLL0_DSM_DIAG 0x0097 -+#define CMN_PLL0_SS_CTRL2 0x0099 -+#define CMN_ICAL_INIT_TMR 0x00c4 -+#define CMN_ICAL_ITER_TMR 0x00c5 -+#define CMN_RXCAL_INIT_TMR 0x00d4 -+#define CMN_RXCAL_ITER_TMR 0x00d5 -+#define CMN_TXPUCAL_CTRL 0x00e0 -+#define CMN_TXPUCAL_INIT_TMR 0x00e4 -+#define CMN_TXPUCAL_ITER_TMR 0x00e5 -+#define CMN_TXPDCAL_CTRL 0x00f0 -+#define CMN_TXPDCAL_INIT_TMR 0x00f4 -+#define CMN_TXPDCAL_ITER_TMR 0x00f5 -+#define CMN_ICAL_ADJ_INIT_TMR 0x0102 -+#define CMN_ICAL_ADJ_ITER_TMR 0x0103 -+#define CMN_RX_ADJ_INIT_TMR 0x0106 -+#define CMN_RX_ADJ_ITER_TMR 0x0107 -+#define CMN_TXPU_ADJ_CTRL 0x0108 -+#define CMN_TXPU_ADJ_INIT_TMR 0x010a -+#define CMN_TXPU_ADJ_ITER_TMR 0x010b -+#define CMN_TXPD_ADJ_CTRL 0x010c -+#define CMN_TXPD_ADJ_INIT_TMR 0x010e -+#define CMN_TXPD_ADJ_ITER_TMR 0x010f -+#define CMN_DIAG_PLL0_FBH_OVRD 0x01c0 -+#define CMN_DIAG_PLL0_FBL_OVRD 0x01c1 -+#define CMN_DIAG_PLL0_OVRD 0x01c2 -+#define CMN_DIAG_PLL0_TEST_MODE 0x01c4 -+#define CMN_DIAG_PLL0_V2I_TUNE 0x01c5 -+#define CMN_DIAG_PLL0_CP_TUNE 0x01c6 -+#define CMN_DIAG_PLL0_LF_PROG 0x01c7 -+#define CMN_DIAG_PLL0_PTATIS_TUNE1 0x01c8 -+#define CMN_DIAG_PLL0_PTATIS_TUNE2 0x01c9 -+#define CMN_DIAG_PLL0_INCLK_CTRL 0x01ca -+#define CMN_DIAG_PLL0_PXL_DIVH 0x01cb -+#define CMN_DIAG_PLL0_PXL_DIVL 0x01cc -+#define CMN_DIAG_HSCLK_SEL 0x01e0 -+#define CMN_DIAG_PER_CAL_ADJ 0x01ec -+#define CMN_DIAG_CAL_CTRL 0x01ed -+#define CMN_DIAG_ACYA 0x01ff -+#define XCVR_PSM_RCTRL 0x4001 -+#define XCVR_PSM_CAL_TMR 0x4002 -+#define XCVR_PSM_A0IN_TMR 0x4003 -+#define TX_TXCC_CAL_SCLR_MULT_0 0x4047 -+#define TX_TXCC_CPOST_MULT_00_0 0x404c -+#define XCVR_DIAG_PLLDRC_CTRL 0x40e0 -+#define XCVR_DIAG_HSCLK_SEL 0x40e1 -+#define XCVR_DIAG_BIDI_CTRL 0x40e8 -+#define XCVR_DIAG_LANE_FCM_EN_MGN_TMR 0x40f2 -+#define TX_PSC_A0 0x4100 -+#define TX_PSC_A1 0x4101 -+#define TX_PSC_A2 0x4102 -+#define TX_PSC_A3 0x4103 -+#define TX_RCVDET_EN_TMR 0x4122 -+#define TX_RCVDET_ST_TMR 0x4123 -+#define TX_DIAG_TX_CTRL 0x41e0 -+#define TX_DIAG_TX_DRV 0x41e1 -+#define TX_DIAG_BGREF_PREDRV_DELAY 0x41e7 -+#define TX_DIAG_ACYA_0 0x41ff -+#define TX_DIAG_ACYA_1 0x43ff -+#define TX_DIAG_ACYA_2 0x45ff -+#define TX_DIAG_ACYA_3 0x47ff -+#define TX_ANA_CTRL_REG_1 0x5020 -+#define TX_ANA_CTRL_REG_2 0x5021 -+#define TX_DIG_CTRL_REG_1 0x5023 -+#define TX_DIG_CTRL_REG_2 0x5024 -+#define TXDA_CYA_AUXDA_CYA 0x5025 -+#define TX_ANA_CTRL_REG_3 0x5026 -+#define TX_ANA_CTRL_REG_4 0x5027 -+#define TX_ANA_CTRL_REG_5 0x5029 -+#define RX_PSC_A0 0x8000 -+#define RX_PSC_CAL 0x8006 -+#define PHY_HDP_MODE_CTRL 0xc008 -+#define PHY_HDP_CLK_CTL 0xc009 -+#define PHY_ISO_CMN_CTRL 0xc010 -+#define PHY_PMA_CMN_CTRL1 0xc800 -+#define PHY_PMA_ISO_CMN_CTRL 0xc810 -+#define PHY_PMA_ISO_PLL_CTRL1 0xc812 -+#define PHY_PMA_ISOLATION_CTRL 0xc81f -+ -+/* PHY_HDP_CLK_CTL */ -+#define PLL_DATA_RATE_CLK_DIV_MASK GENMASK(15, 8) -+#define PLL_DATA_RATE_CLK_DIV_HBR 0x24 -+#define PLL_DATA_RATE_CLK_DIV_HBR2 0x12 -+#define PLL_CLK_EN_ACK BIT(3) -+#define PLL_CLK_EN BIT(2) -+#define PLL_READY BIT(1) -+#define PLL_EN BIT(0) -+ -+/* PHY_PMA_CMN_CTRL1 */ -+#define CMA_REF_CLK_DIG_DIV_MASK GENMASK(13, 12) -+#define CMA_REF_CLK_SEL_MASK GENMASK(6, 4) -+#define CMA_REF_CLK_RCV_EN_MASK BIT(3) -+#define CMA_REF_CLK_RCV_EN 1 -+#define CMN_READY BIT(0) -+ -+/* PHY_PMA_ISO_PLL_CTRL1 */ -+#define CMN_PLL0_CLK_DATART_DIV_MASK GENMASK(7, 0) -+ -+/* TX_DIAG_TX_DRV */ -+#define TX_DRIVER_PROG_BOOST_ENABLE BIT(10) -+#define TX_DRIVER_PROG_BOOST_LEVEL_MASK GENMASK(9, 8) -+#define TX_DRIVER_LDO_BG_DEPENDENT_REF_ENABLE BIT(7) -+#define TX_DRIVER_LDO_BANDGAP_REF_ENABLE BIT(6) -+ -+/* TX_TXCC_CAL_SCLR_MULT_0 */ -+#define SCALED_RESISTOR_CALIBRATION_CODE_ADD BIT(8) -+#define RESISTOR_CAL_MULT_VAL_32_128 BIT(5) -+ -+/* CMN_CDIAG_REFCLK_CTRL */ -+#define DIG_REF_CLK_DIV_SCALER_MASK GENMASK(14, 12) -+#define REFCLK_TERMINATION_EN_OVERRIDE_EN BIT(7) -+#define REFCLK_TERMINATION_EN_OVERRIDE BIT(6) -+ -+/* CMN_DIAG_HSCLK_SEL */ -+#define HSCLK1_SEL_MASK GENMASK(5, 4) -+#define HSCLK0_SEL_MASK GENMASK(1, 0) -+#define HSCLK_PLL0_DIV2 1 -+ -+/* XCVR_DIAG_HSCLK_SEL */ -+#define HSCLK_SEL_MODE3_MASK GENMASK(13, 12) -+#define HSCLK_SEL_MODE3_HSCLK1 1 -+ -+/* CMN_PLL0_VCOCAL_START */ -+#define VCO_CALIB_CODE_START_POINT_VAL_MASK GENMASK(8, 0) -+ -+/* CMN_DIAG_PLL0_FBH_OVRD */ -+#define PLL_FEEDBACK_DIV_HI_OVERRIDE_EN BIT(15) -+ -+/* CMN_DIAG_PLL0_FBL_OVRD */ -+#define PLL_FEEDBACK_DIV_LO_OVERRIDE_EN BIT(15) -+ -+/* CMN_DIAG_PLL0_PXL_DIVH */ -+#define PLL_PCLK_DIV_EN BIT(15) -+ -+/* XCVR_DIAG_PLLDRC_CTRL */ -+#define DPLL_CLK_SEL_MODE3 BIT(14) -+#define DPLL_DATA_RATE_DIV_MODE3_MASK GENMASK(13, 12) -+ -+/* TX_DIAG_TX_CTRL */ -+#define TX_IF_SUBRATE_MODE3_MASK GENMASK(7, 6) -+ -+/* PHY_HDP_MODE_CTRL */ -+#define POWER_STATE_A3_ACK BIT(7) -+#define POWER_STATE_A2_ACK BIT(6) -+#define POWER_STATE_A1_ACK BIT(5) -+#define POWER_STATE_A0_ACK BIT(4) -+#define POWER_STATE_A3 BIT(3) -+#define POWER_STATE_A2 BIT(2) -+#define POWER_STATE_A1 BIT(1) -+#define POWER_STATE_A0 BIT(0) -+ -+/* PHY_PMA_ISO_CMN_CTRL */ -+#define CMN_MACRO_PWR_EN_ACK BIT(5) -+ -+#define KEEP_ALIVE 0x18 -+ -+/* FW check alive timeout */ -+#define CDNS_KEEP_ALIVE_TIMEOUT 2000 -+#define CDNS_KEEP_ALIVE_MASK GENMASK(7, 0) -+ -+#define REF_CLK_27MHZ 27000000 -+ -+#define LINK_RATE_2_7 270000 -+#define MAX_LINK_RATE 540000 -+ -+#define CMN_REF_CLK_DIG_DIV 1 -+#define REF_CLK_DIVIDER_SCALER 1 -+ -+/* HDMI TX clock control settings */ -+struct hdptx_hdmi_ctrl { -+ u32 pixel_clk_freq; -+ u32 feedback_factor; -+ u32 cmnda_pll0_ip_div; -+ u32 pll_fb_div_total; -+ u32 cmnda_pll0_fb_div_low; -+ u32 cmnda_pll0_fb_div_high; -+ u32 cmnda_pll0_pxdiv_low; -+ u32 cmnda_pll0_pxdiv_high; -+ u32 vco_ring_select; -+ u32 cmnda_hs_clk_0_sel; -+ u32 cmnda_hs_clk_1_sel; -+ u32 hsclk_div_tx_sub_rate; -+ u32 cmnda_pll0_hs_sym_div_sel; -+}; -+ -+struct cdns_hdptx_phy { -+ struct cdns_mhdp_base base; -+ -+ void __iomem *regs; /* DPTX registers base */ -+ struct device *dev; -+ struct phy *phy; -+ struct clk *ref_clk, *apb_clk; -+ u32 ref_clk_rate; -+ union { -+ struct phy_configure_opts_hdmi hdmi; -+ struct phy_configure_opts_dp dp; -+ }; -+}; -+ -+/* HDMI TX clock control settings, pixel clock is output */ -+static const struct hdptx_hdmi_ctrl pixel_clk_output_ctrl_table[] = { -+ /* clk fbak ipd totl div_l div_h pd_l pd_h v h1 h2 sub sym*/ -+ { 27000, 1000, 3, 240, 0x0bc, 0x30, 0x26, 0x26, 0, 2, 2, 4, 3 }, -+ { 27000, 1250, 3, 300, 0x0ec, 0x3c, 0x30, 0x30, 0, 2, 2, 4, 3 }, -+ { 27000, 1500, 3, 360, 0x11c, 0x48, 0x3a, 0x3a, 0, 2, 2, 4, 3 }, -+ { 27000, 2000, 3, 240, 0x0bc, 0x30, 0x26, 0x26, 0, 2, 2, 4, 2 }, -+ { 54000, 1000, 3, 480, 0x17c, 0x60, 0x26, 0x26, 1, 2, 2, 4, 3 }, -+ { 54000, 1250, 4, 400, 0x13c, 0x50, 0x17, 0x17, 0, 1, 1, 4, 2 }, -+ { 54000, 1500, 4, 480, 0x17c, 0x60, 0x1c, 0x1c, 0, 2, 2, 2, 2 }, -+ { 54000, 2000, 3, 240, 0x0bc, 0x30, 0x12, 0x12, 0, 2, 2, 1, 1 }, -+ { 74250, 1000, 3, 660, 0x20c, 0x84, 0x26, 0x26, 1, 2, 2, 4, 3 }, -+ { 74250, 1250, 4, 550, 0x1b4, 0x6e, 0x17, 0x17, 1, 1, 1, 4, 2 }, -+ { 74250, 1500, 4, 660, 0x20c, 0x84, 0x1c, 0x1c, 1, 2, 2, 2, 2 }, -+ { 74250, 2000, 3, 330, 0x104, 0x42, 0x12, 0x12, 0, 2, 2, 1, 1 }, -+ { 99000, 1000, 3, 440, 0x15c, 0x58, 0x12, 0x12, 1, 2, 2, 2, 2 }, -+ { 99000, 1250, 3, 275, 0x0d8, 0x37, 0x0b, 0x0a, 0, 1, 1, 2, 1 }, -+ { 99000, 1500, 3, 330, 0x104, 0x42, 0x0d, 0x0d, 0, 2, 2, 1, 1 }, -+ { 99000, 2000, 3, 440, 0x15c, 0x58, 0x12, 0x12, 1, 2, 2, 1, 1 }, -+ { 148500, 1000, 3, 660, 0x20c, 0x84, 0x12, 0x12, 1, 2, 2, 2, 2 }, -+ { 148500, 1250, 4, 550, 0x1b4, 0x6e, 0x0b, 0x0a, 1, 1, 1, 2, 1 }, -+ { 148500, 1500, 3, 495, 0x188, 0x63, 0x0d, 0x0d, 1, 1, 1, 2, 1 }, -+ { 148500, 2000, 3, 660, 0x20c, 0x84, 0x12, 0x12, 1, 2, 2, 1, 1 }, -+ { 198000, 1000, 3, 220, 0x0ac, 0x2c, 0x03, 0x03, 0, 1, 1, 1, 0 }, -+ { 198000, 1250, 3, 550, 0x1b4, 0x6e, 0x0b, 0x0a, 1, 1, 1, 2, 1 }, -+ { 198000, 1500, 3, 330, 0x104, 0x42, 0x06, 0x05, 0, 1, 1, 1, 0 }, -+ { 198000, 2000, 3, 440, 0x15c, 0x58, 0x08, 0x08, 1, 1, 1, 1, 0 }, -+ { 297000, 1000, 3, 330, 0x104, 0x42, 0x03, 0x03, 0, 1, 1, 1, 0 }, -+ { 297000, 1500, 3, 495, 0x188, 0x63, 0x06, 0x05, 1, 1, 1, 1, 0 }, -+ { 297000, 2000, 3, 660, 0x20c, 0x84, 0x08, 0x08, 1, 1, 1, 1, 0 }, -+ { 594000, 1000, 3, 660, 0x20c, 0x84, 0x03, 0x03, 1, 1, 1, 1, 0 }, -+ { 594000, 750, 3, 495, 0x188, 0x63, 0x03, 0x03, 1, 1, 1, 1, 0 }, -+ { 594000, 625, 4, 550, 0x1b4, 0x6e, 0x03, 0x03, 1, 1, 1, 1, 0 }, -+ { 594000, 500, 3, 660, 0x20c, 0x84, 0x03, 0x03, 1, 1, 1, 2, 1 }, -+}; -+ -+/* HDMI TX PLL tuning settings */ -+struct hdptx_hdmi_pll_tuning { -+ u32 vco_freq; -+ u32 volt_to_current_coarse; -+ u32 volt_to_current; -+ u32 ndac_ctrl; -+ u32 pmos_ctrl; -+ u32 ptat_ndac_ctrl; -+ u32 feedback_div_total; -+ u32 charge_pump_gain; -+ u32 vco_cal_code; -+}; -+ -+/* HDMI TX PLL tuning settings, pixel clock is output */ -+static const struct hdptx_hdmi_pll_tuning pixel_clk_output_pll_table[] = { -+ /*VCO_f coar cu nd pm ptat fd_d gain cal */ -+ { 1980000, 4, 3, 0, 9, 0x9, 220, 0x42, 183 }, -+ { 2160000, 4, 3, 0, 9, 0x9, 240, 0x42, 208 }, -+ { 2475000, 5, 3, 1, 0, 0x7, 275, 0x42, 209 }, -+ { 2700000, 5, 3, 1, 0, 0x7, 300, 0x42, 230 }, -+ { 2700000, 5, 3, 1, 0, 0x7, 400, 0x4c, 230 }, -+ { 2970000, 6, 3, 1, 0, 0x7, 330, 0x42, 225 }, -+ { 3240000, 6, 3, 1, 0, 0x7, 360, 0x42, 256 }, -+ { 3240000, 6, 3, 1, 0, 0x7, 480, 0x4c, 256 }, -+ { 3712500, 4, 3, 0, 7, 0xF, 550, 0x4c, 257 }, -+ { 3960000, 5, 3, 0, 7, 0xF, 440, 0x42, 226 }, -+ { 4320000, 5, 3, 1, 7, 0xF, 480, 0x42, 258 }, -+ { 4455000, 5, 3, 0, 7, 0xF, 495, 0x42, 272 }, -+ { 4455000, 5, 3, 0, 7, 0xF, 660, 0x4c, 272 }, -+ { 4950000, 6, 3, 1, 0, 0x7, 550, 0x42, 258 }, -+ { 5940000, 7, 3, 1, 0, 0x7, 660, 0x42, 292 }, -+}; -+ -+struct phy_pll_reg { -+ u16 val[7]; -+ u32 addr; -+}; -+ -+static const struct phy_pll_reg phy_pll_27m_cfg[] = { -+ /* 1.62 2.16 2.43 2.7 3.24 4.32 5.4 register address */ -+ {{ 0x010e, 0x010e, 0x010e, 0x010e, 0x010e, 0x010e, 0x010e }, CMN_PLL0_VCOCAL_INIT_TMR }, -+ {{ 0x001b, 0x001b, 0x001b, 0x001b, 0x001b, 0x001b, 0x001b }, CMN_PLL0_VCOCAL_ITER_TMR }, -+ {{ 0x30b9, 0x3087, 0x3096, 0x30b4, 0x30b9, 0x3087, 0x30b4 }, CMN_PLL0_VCOCAL_START }, -+ {{ 0x0077, 0x009f, 0x00b3, 0x00c7, 0x0077, 0x009f, 0x00c7 }, CMN_PLL0_INTDIV }, -+ {{ 0xf9da, 0xf7cd, 0xf6c7, 0xf5c1, 0xf9da, 0xf7cd, 0xf5c1 }, CMN_PLL0_FRACDIV }, -+ {{ 0x001e, 0x0028, 0x002d, 0x0032, 0x001e, 0x0028, 0x0032 }, CMN_PLL0_HIGH_THR }, -+ {{ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020 }, CMN_PLL0_DSM_DIAG }, -+ {{ 0x0000, 0x1000, 0x1000, 0x1000, 0x0000, 0x1000, 0x1000 }, CMN_PLLSM0_USER_DEF_CTRL }, -+ {{ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, CMN_DIAG_PLL0_OVRD }, -+ {{ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, CMN_DIAG_PLL0_FBH_OVRD }, -+ {{ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, CMN_DIAG_PLL0_FBL_OVRD }, -+ {{ 0x0006, 0x0007, 0x0007, 0x0007, 0x0006, 0x0007, 0x0007 }, CMN_DIAG_PLL0_V2I_TUNE }, -+ {{ 0x0043, 0x0043, 0x0043, 0x0042, 0x0043, 0x0043, 0x0042 }, CMN_DIAG_PLL0_CP_TUNE }, -+ {{ 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008 }, CMN_DIAG_PLL0_LF_PROG }, -+ {{ 0x0100, 0x0001, 0x0001, 0x0001, 0x0100, 0x0001, 0x0001 }, CMN_DIAG_PLL0_PTATIS_TUNE1 }, -+ {{ 0x0007, 0x0001, 0x0001, 0x0001, 0x0007, 0x0001, 0x0001 }, CMN_DIAG_PLL0_PTATIS_TUNE2 }, -+ {{ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020 }, CMN_DIAG_PLL0_TEST_MODE}, -+ {{ 0x0016, 0x0016, 0x0016, 0x0016, 0x0016, 0x0016, 0x0016 }, CMN_PSM_CLK_CTRL } -+}; -+ -+static int dp_link_rate_index(u32 rate) -+{ -+ switch (rate) { -+ case 162000: -+ return 0; -+ case 216000: -+ return 1; -+ case 243000: -+ return 2; -+ case 270000: -+ return 3; -+ case 324000: -+ return 4; -+ case 432000: -+ return 5; -+ case 540000: -+ return 6; -+ default: -+ return -EINVAL; -+ } -+} -+ -+static int cdns_phy_reg_write(struct cdns_hdptx_phy *cdns_phy, u32 addr, u32 val) -+{ -+ return cdns_mhdp_reg_write(&cdns_phy->base, ADDR_PHY_AFE + (addr << 2), val); -+} -+ -+static u32 cdns_phy_reg_read(struct cdns_hdptx_phy *cdns_phy, u32 addr) -+{ -+ u32 reg32; -+ -+ cdns_mhdp_reg_read(&cdns_phy->base, ADDR_PHY_AFE + (addr << 2), ®32); -+ -+ return reg32; -+} -+ -+static void hdptx_dp_aux_cfg(struct cdns_hdptx_phy *cdns_phy) -+{ -+ /* Power up Aux */ -+ cdns_phy_reg_write(cdns_phy, TXDA_CYA_AUXDA_CYA, 1); -+ -+ cdns_phy_reg_write(cdns_phy, TX_DIG_CTRL_REG_1, 0x3); -+ ndelay(150); -+ cdns_phy_reg_write(cdns_phy, TX_DIG_CTRL_REG_2, 36); -+ ndelay(150); -+ cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x0100); -+ ndelay(150); -+ cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x0300); -+ ndelay(150); -+ cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_3, 0x0000); -+ ndelay(150); -+ cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0x2008); -+ ndelay(150); -+ cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0x2018); -+ ndelay(150); -+ cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0xa018); -+ ndelay(150); -+ cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x030c); -+ ndelay(150); -+ cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_5, 0x0000); -+ ndelay(150); -+ cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_4, 0x1001); -+ ndelay(150); -+ cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0xa098); -+ ndelay(150); -+ cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0xa198); -+ ndelay(150); -+ cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x030d); -+ ndelay(150); -+ cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x030f); -+} -+ -+/* PMA common configuration for 27MHz */ -+static void hdptx_dp_phy_pma_cmn_cfg_27mhz(struct cdns_hdptx_phy *cdns_phy) -+{ -+ u32 num_lanes = cdns_phy->dp.lanes; -+ u16 val; -+ int k; -+ -+ /* Enable PMA input ref clk(CMN_REF_CLK_RCV_EN) */ -+ val = cdns_phy_reg_read(cdns_phy, PHY_PMA_CMN_CTRL1); -+ val &= ~CMA_REF_CLK_RCV_EN_MASK; -+ val |= FIELD_PREP(CMA_REF_CLK_RCV_EN_MASK, CMA_REF_CLK_RCV_EN); -+ cdns_phy_reg_write(cdns_phy, PHY_PMA_CMN_CTRL1, val); -+ -+ /* Startup state machine registers */ -+ cdns_phy_reg_write(cdns_phy, CMN_SSM_BIAS_TMR, 0x0087); -+ cdns_phy_reg_write(cdns_phy, CMN_PLLSM0_PLLEN_TMR, 0x001b); -+ cdns_phy_reg_write(cdns_phy, CMN_PLLSM0_PLLPRE_TMR, 0x0036); -+ cdns_phy_reg_write(cdns_phy, CMN_PLLSM0_PLLVREF_TMR, 0x001b); -+ cdns_phy_reg_write(cdns_phy, CMN_PLLSM0_PLLLOCK_TMR, 0x006c); -+ -+ /* Current calibration registers */ -+ cdns_phy_reg_write(cdns_phy, CMN_ICAL_INIT_TMR, 0x0044); -+ cdns_phy_reg_write(cdns_phy, CMN_ICAL_ITER_TMR, 0x0006); -+ cdns_phy_reg_write(cdns_phy, CMN_ICAL_ADJ_INIT_TMR, 0x0022); -+ cdns_phy_reg_write(cdns_phy, CMN_ICAL_ADJ_ITER_TMR, 0x0006); -+ -+ /* Resistor calibration registers */ -+ cdns_phy_reg_write(cdns_phy, CMN_TXPUCAL_INIT_TMR, 0x0022); -+ cdns_phy_reg_write(cdns_phy, CMN_TXPUCAL_ITER_TMR, 0x0006); -+ cdns_phy_reg_write(cdns_phy, CMN_TXPU_ADJ_INIT_TMR, 0x0022); -+ cdns_phy_reg_write(cdns_phy, CMN_TXPU_ADJ_ITER_TMR, 0x0006); -+ cdns_phy_reg_write(cdns_phy, CMN_TXPDCAL_INIT_TMR, 0x0022); -+ cdns_phy_reg_write(cdns_phy, CMN_TXPDCAL_ITER_TMR, 0x0006); -+ cdns_phy_reg_write(cdns_phy, CMN_TXPD_ADJ_INIT_TMR, 0x0022); -+ cdns_phy_reg_write(cdns_phy, CMN_TXPD_ADJ_ITER_TMR, 0x0006); -+ cdns_phy_reg_write(cdns_phy, CMN_RXCAL_INIT_TMR, 0x0022); -+ cdns_phy_reg_write(cdns_phy, CMN_RXCAL_ITER_TMR, 0x0006); -+ cdns_phy_reg_write(cdns_phy, CMN_RX_ADJ_INIT_TMR, 0x0022); -+ cdns_phy_reg_write(cdns_phy, CMN_RX_ADJ_ITER_TMR, 0x0006); -+ -+ for (k = 0; k < num_lanes; k = k + 1) { -+ /* Power state machine registers */ -+ cdns_phy_reg_write(cdns_phy, XCVR_PSM_CAL_TMR | (k << 9), 0x016d); -+ cdns_phy_reg_write(cdns_phy, XCVR_PSM_A0IN_TMR | (k << 9), 0x016d); -+ /* Transceiver control and diagnostic registers */ -+ cdns_phy_reg_write(cdns_phy, XCVR_DIAG_LANE_FCM_EN_MGN_TMR | (k << 9), 0x00a2); -+ cdns_phy_reg_write(cdns_phy, TX_DIAG_BGREF_PREDRV_DELAY | (k << 9), 0x0097); -+ /* Transmitter receiver detect registers */ -+ cdns_phy_reg_write(cdns_phy, TX_RCVDET_EN_TMR | (k << 9), 0x0a8c); -+ cdns_phy_reg_write(cdns_phy, TX_RCVDET_ST_TMR | (k << 9), 0x0036); -+ } -+ -+ cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_0, 1); -+ cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_1, 1); -+ cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_2, 1); -+ cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_3, 1); -+} -+ -+static void hdptx_dp_phy_pma_cmn_pll0_27mhz(struct cdns_hdptx_phy *cdns_phy) -+{ -+ u32 num_lanes = cdns_phy->dp.lanes; -+ u32 link_rate = cdns_phy->dp.link_rate; -+ u16 val; -+ int index, i, k; -+ -+ /* DP PLL data rate 0/1 clock divider value */ -+ val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL); -+ val &= ~PLL_DATA_RATE_CLK_DIV_MASK; -+ if (link_rate <= LINK_RATE_2_7) -+ val |= FIELD_PREP(PLL_DATA_RATE_CLK_DIV_MASK, -+ PLL_DATA_RATE_CLK_DIV_HBR); -+ else -+ val |= FIELD_PREP(PLL_DATA_RATE_CLK_DIV_MASK, -+ PLL_DATA_RATE_CLK_DIV_HBR2); -+ cdns_phy_reg_write(cdns_phy, PHY_HDP_CLK_CTL, val); -+ -+ /* High speed clock 0/1 div */ -+ val = cdns_phy_reg_read(cdns_phy, CMN_DIAG_HSCLK_SEL); -+ val &= ~(HSCLK1_SEL_MASK | HSCLK0_SEL_MASK); -+ if (link_rate <= LINK_RATE_2_7) { -+ val |= FIELD_PREP(HSCLK1_SEL_MASK, HSCLK_PLL0_DIV2); -+ val |= FIELD_PREP(HSCLK0_SEL_MASK, HSCLK_PLL0_DIV2); -+ } -+ cdns_phy_reg_write(cdns_phy, CMN_DIAG_HSCLK_SEL, val); -+ -+ for (k = 0; k < num_lanes; k++) { -+ val = cdns_phy_reg_read(cdns_phy, (XCVR_DIAG_HSCLK_SEL | (k << 9))); -+ val &= ~HSCLK_SEL_MODE3_MASK; -+ if (link_rate <= LINK_RATE_2_7) -+ val |= FIELD_PREP(HSCLK_SEL_MODE3_MASK, HSCLK_SEL_MODE3_HSCLK1); -+ cdns_phy_reg_write(cdns_phy, (XCVR_DIAG_HSCLK_SEL | (k << 9)), val); -+ } -+ -+ /* DP PHY PLL 27MHz configuration */ -+ index = dp_link_rate_index(link_rate); -+ if (index < 0) { -+ dev_err(cdns_phy->dev, "Not support link rate %d\n", link_rate); -+ return; -+ } -+ -+ for (i = 0; i < ARRAY_SIZE(phy_pll_27m_cfg); i++) -+ cdns_phy_reg_write(cdns_phy, phy_pll_27m_cfg[i].addr, -+ phy_pll_27m_cfg[i].val[index]); -+ -+ /* Transceiver control and diagnostic registers */ -+ for (k = 0; k < num_lanes; k++) { -+ val = cdns_phy_reg_read(cdns_phy, (XCVR_DIAG_PLLDRC_CTRL | (k << 9))); -+ val &= ~(DPLL_DATA_RATE_DIV_MODE3_MASK | DPLL_CLK_SEL_MODE3); -+ if (link_rate <= LINK_RATE_2_7) -+ val |= FIELD_PREP(DPLL_DATA_RATE_DIV_MODE3_MASK, 2); -+ else -+ val |= FIELD_PREP(DPLL_DATA_RATE_DIV_MODE3_MASK, 1); -+ cdns_phy_reg_write(cdns_phy, (XCVR_DIAG_PLLDRC_CTRL | (k << 9)), val); -+ } -+ -+ for (k = 0; k < num_lanes; k = k + 1) { -+ /* Power state machine registers */ -+ cdns_phy_reg_write(cdns_phy, (XCVR_PSM_RCTRL | (k << 9)), 0xbefc); -+ cdns_phy_reg_write(cdns_phy, (TX_PSC_A0 | (k << 9)), 0x6799); -+ cdns_phy_reg_write(cdns_phy, (TX_PSC_A1 | (k << 9)), 0x6798); -+ cdns_phy_reg_write(cdns_phy, (TX_PSC_A2 | (k << 9)), 0x0098); -+ cdns_phy_reg_write(cdns_phy, (TX_PSC_A3 | (k << 9)), 0x0098); -+ /* Receiver calibration power state definition register */ -+ val = cdns_phy_reg_read(cdns_phy, RX_PSC_CAL | (k << 9)); -+ val &= 0xffbb; -+ cdns_phy_reg_write(cdns_phy, (RX_PSC_CAL | (k << 9)), val); -+ val = cdns_phy_reg_read(cdns_phy, RX_PSC_A0 | (k << 9)); -+ val &= 0xffbb; -+ cdns_phy_reg_write(cdns_phy, (RX_PSC_A0 | (k << 9)), val); -+ } -+} -+ -+static void hdptx_dp_phy_ref_clock_type(struct cdns_hdptx_phy *cdns_phy) -+{ -+ u32 val; -+ -+ val = cdns_phy_reg_read(cdns_phy, PHY_PMA_CMN_CTRL1); -+ val &= ~CMA_REF_CLK_SEL_MASK; -+ /* -+ * single ended reference clock (val |= 0x0030); -+ * differential clock (val |= 0x0000); -+ * -+ * for differential clock on the refclk_p and -+ * refclk_m off chip pins: CMN_DIAG_ACYA[8]=1'b1 -+ * cdns_phy_reg_write(cdns_phy, CMN_DIAG_ACYA, 0x0100); -+ */ -+ val |= FIELD_PREP(CMA_REF_CLK_SEL_MASK, 3); -+ cdns_phy_reg_write(cdns_phy, PHY_PMA_CMN_CTRL1, val); -+} -+ -+static int wait_for_ack(struct cdns_hdptx_phy *cdns_phy, -+ u32 reg, u32 mask, -+ const char *err_msg) -+{ -+ int ret; -+ u32 val; -+ -+ ret = read_poll_timeout(cdns_phy_reg_read, -+ val, val & mask, 20, 1000, -+ false, cdns_phy, reg); -+ if (ret < 0) -+ dev_err(cdns_phy->dev, "%s\n", err_msg); -+ -+ return ret; -+} -+ -+static int wait_for_ack_clear(struct cdns_hdptx_phy *cdns_phy, -+ u32 reg, u32 mask, -+ const char *err_msg) -+{ -+ int ret; -+ u32 val; -+ -+ ret = read_poll_timeout(cdns_phy_reg_read, -+ val, !(val & mask), 20, 1000, -+ false, cdns_phy, reg); -+ if (ret < 0) -+ dev_err(cdns_phy->dev, "%s\n", err_msg); -+ -+ return ret; -+} -+ -+static int hdptx_dp_phy_power_up(struct cdns_hdptx_phy *cdns_phy) -+{ -+ u32 val; -+ int ret; -+ -+ /* Enable HDP PLL's for high speed clocks */ -+ val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL); -+ val |= PLL_EN; -+ cdns_phy_reg_write(cdns_phy, PHY_HDP_CLK_CTL, val); -+ ret = wait_for_ack(cdns_phy, PHY_HDP_CLK_CTL, PLL_READY, -+ "Wait PLL Ack failed"); -+ if (ret < 0) -+ return ret; -+ -+ /* Enable HDP PLL's data rate and full rate clocks out of PMA. */ -+ val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL); -+ val |= PLL_CLK_EN; -+ cdns_phy_reg_write(cdns_phy, PHY_HDP_CLK_CTL, val); -+ ret = wait_for_ack(cdns_phy, PHY_HDP_CLK_CTL, PLL_CLK_EN_ACK, -+ "Wait PLL clock enable ACK failed"); -+ if (ret < 0) -+ return ret; -+ -+ /* Configure PHY in A2 Mode */ -+ cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A2); -+ ret = wait_for_ack(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A2_ACK, -+ "Wait A2 Ack failed"); -+ if (ret < 0) -+ return ret; -+ -+ /* Configure PHY in A0 mode (PHY must be in the A0 power -+ * state in order to transmit data) -+ */ -+ cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A0); -+ -+ return wait_for_ack(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A0_ACK, -+ "Wait A0 Ack failed"); -+} -+ -+static int hdptx_dp_phy_power_down(struct cdns_hdptx_phy *cdns_phy) -+{ -+ u16 val; -+ int ret; -+ -+ /* Place the PHY lanes in the A3 power state. */ -+ cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A3); -+ ret = wait_for_ack(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A3_ACK, -+ "Wait A3 Ack failed"); -+ if (ret) -+ return ret; -+ -+ /* Disable HDP PLL's data rate and full rate clocks out of PMA. */ -+ val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL); -+ val &= ~PLL_CLK_EN; -+ cdns_phy_reg_write(cdns_phy, PHY_HDP_CLK_CTL, val); -+ ret = wait_for_ack_clear(cdns_phy, PHY_HDP_CLK_CTL, PLL_CLK_EN_ACK, -+ "Wait PLL clock Ack clear failed"); -+ if (ret) -+ return ret; -+ -+ /* Disable HDP PLL's for high speed clocks */ -+ val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL); -+ val &= ~PLL_EN; -+ cdns_phy_reg_write(cdns_phy, PHY_HDP_CLK_CTL, val); -+ -+ return wait_for_ack_clear(cdns_phy, PHY_HDP_CLK_CTL, PLL_READY, -+ "Wait PLL Ack clear failed"); -+} -+ -+static int hdptx_dp_configure(struct phy *phy, -+ union phy_configure_opts *opts) -+{ -+ struct cdns_hdptx_phy *cdns_phy = phy_get_drvdata(phy); -+ -+ cdns_phy->dp.link_rate = opts->dp.link_rate; -+ cdns_phy->dp.lanes = opts->dp.lanes; -+ -+ if (cdns_phy->dp.link_rate > MAX_LINK_RATE) { -+ dev_err(cdns_phy->dev, "Link Rate(%d) Not supported\n", cdns_phy->dp.link_rate); -+ return false; -+ } -+ -+ if (cdns_phy->ref_clk_rate == REF_CLK_27MHZ) { -+ hdptx_dp_phy_pma_cmn_cfg_27mhz(cdns_phy); -+ hdptx_dp_phy_pma_cmn_pll0_27mhz(cdns_phy); -+ } else { -+ dev_err(cdns_phy->dev, "Not support ref clock rate\n"); -+ } -+ -+ return 0; -+} -+ -+static int hdptx_clk_enable(struct cdns_hdptx_phy *cdns_phy) -+{ -+ struct device *dev = cdns_phy->dev; -+ u32 ref_clk_rate; -+ -+ cdns_phy->ref_clk = devm_clk_get_enabled(dev, "ref"); -+ if (IS_ERR(cdns_phy->ref_clk)) { -+ dev_err(dev, "phy ref clock not found\n"); -+ return PTR_ERR(cdns_phy->ref_clk); -+ } -+ -+ ref_clk_rate = clk_get_rate(cdns_phy->ref_clk); -+ if (!ref_clk_rate) { -+ dev_err(cdns_phy->dev, "Failed to get ref clock rate\n"); -+ return -EINVAL; -+ } -+ -+ if (ref_clk_rate == REF_CLK_27MHZ) { -+ cdns_phy->ref_clk_rate = ref_clk_rate; -+ } else { -+ dev_err(cdns_phy->dev, "Not support Ref Clock Rate(%dHz)\n", ref_clk_rate); -+ return -EINVAL; -+ } -+ -+ cdns_phy->apb_clk = devm_clk_get_enabled(dev, "apb"); -+ if (IS_ERR(cdns_phy->apb_clk)) { -+ dev_err(dev, "phy apb clock not found\n"); -+ return PTR_ERR(cdns_phy->apb_clk); -+ } -+ -+ return 0; -+} -+ -+static void hdptx_hdmi_arc_config(struct cdns_hdptx_phy *cdns_phy) -+{ -+ u16 txpu_calib_code; -+ u16 txpd_calib_code; -+ u16 txpu_adj_calib_code; -+ u16 txpd_adj_calib_code; -+ u16 prev_calib_code; -+ u16 new_calib_code; -+ u16 rdata; -+ -+ /* Power ARC */ -+ cdns_phy_reg_write(cdns_phy, TXDA_CYA_AUXDA_CYA, 0x0001); -+ -+ prev_calib_code = cdns_phy_reg_read(cdns_phy, TX_DIG_CTRL_REG_2); -+ txpu_calib_code = cdns_phy_reg_read(cdns_phy, CMN_TXPUCAL_CTRL); -+ txpd_calib_code = cdns_phy_reg_read(cdns_phy, CMN_TXPDCAL_CTRL); -+ txpu_adj_calib_code = cdns_phy_reg_read(cdns_phy, CMN_TXPU_ADJ_CTRL); -+ txpd_adj_calib_code = cdns_phy_reg_read(cdns_phy, CMN_TXPD_ADJ_CTRL); -+ -+ new_calib_code = ((txpu_calib_code + txpd_calib_code) / 2) -+ + txpu_adj_calib_code + txpd_adj_calib_code; -+ -+ if (new_calib_code != prev_calib_code) { -+ rdata = cdns_phy_reg_read(cdns_phy, TX_ANA_CTRL_REG_1); -+ rdata &= 0xdfff; -+ cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, rdata); -+ cdns_phy_reg_write(cdns_phy, TX_DIG_CTRL_REG_2, new_calib_code); -+ mdelay(10); -+ rdata |= 0x2000; -+ cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, rdata); -+ usleep_range(150, 250); -+ } -+ -+ cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x0100); -+ usleep_range(100, 200); -+ cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x0300); -+ usleep_range(100, 200); -+ cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_3, 0x0000); -+ usleep_range(100, 200); -+ cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0x2008); -+ usleep_range(100, 200); -+ cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0x2018); -+ usleep_range(100, 200); -+ cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0x2098); -+ cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x030c); -+ cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_5, 0x0010); -+ usleep_range(100, 200); -+ cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_4, 0x4001); -+ mdelay(5); -+ cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0x2198); -+ mdelay(5); -+ cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x030d); -+ usleep_range(100, 200); -+ cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x030f); -+} -+ -+static void hdptx_hdmi_phy_set_vswing(struct cdns_hdptx_phy *cdns_phy) -+{ -+ u32 k; -+ const u32 num_lanes = 4; -+ -+ for (k = 0; k < num_lanes; k++) { -+ cdns_phy_reg_write(cdns_phy, (TX_DIAG_TX_DRV | (k << 9)), -+ TX_DRIVER_PROG_BOOST_ENABLE | -+ FIELD_PREP(TX_DRIVER_PROG_BOOST_LEVEL_MASK, 3) | -+ TX_DRIVER_LDO_BG_DEPENDENT_REF_ENABLE | -+ TX_DRIVER_LDO_BANDGAP_REF_ENABLE); -+ cdns_phy_reg_write(cdns_phy, (TX_TXCC_CPOST_MULT_00_0 | (k << 9)), 0x0); -+ cdns_phy_reg_write(cdns_phy, (TX_TXCC_CAL_SCLR_MULT_0 | (k << 9)), -+ SCALED_RESISTOR_CALIBRATION_CODE_ADD | -+ RESISTOR_CAL_MULT_VAL_32_128); -+ } -+} -+ -+static int hdptx_hdmi_phy_config(struct cdns_hdptx_phy *cdns_phy, -+ const struct hdptx_hdmi_ctrl *p_ctrl_table, -+ const struct hdptx_hdmi_pll_tuning *p_pll_table, -+ bool pclk_in) -+{ -+ const u32 num_lanes = 4; -+ u32 val, k; -+ int ret; -+ -+ /* enable PHY isolation mode only for CMN */ -+ cdns_phy_reg_write(cdns_phy, PHY_PMA_ISOLATION_CTRL, 0xd000); -+ -+ /* set cmn_pll0_clk_datart1_div/cmn_pll0_clk_datart0_div dividers */ -+ val = cdns_phy_reg_read(cdns_phy, PHY_PMA_ISO_PLL_CTRL1); -+ val &= ~CMN_PLL0_CLK_DATART_DIV_MASK; -+ val |= FIELD_PREP(CMN_PLL0_CLK_DATART_DIV_MASK, 0x12); -+ cdns_phy_reg_write(cdns_phy, PHY_PMA_ISO_PLL_CTRL1, val); -+ -+ /* assert PHY reset from isolation register */ -+ cdns_phy_reg_write(cdns_phy, PHY_ISO_CMN_CTRL, 0x0000); -+ /* assert PMA CMN reset */ -+ cdns_phy_reg_write(cdns_phy, PHY_PMA_ISO_CMN_CTRL, 0x0000); -+ -+ /* register XCVR_DIAG_BIDI_CTRL */ -+ for (k = 0; k < num_lanes; k++) -+ cdns_phy_reg_write(cdns_phy, XCVR_DIAG_BIDI_CTRL | (k << 9), 0x00ff); -+ -+ /* Describing Task phy_cfg_hdp */ -+ val = cdns_phy_reg_read(cdns_phy, PHY_PMA_CMN_CTRL1); -+ val &= ~CMA_REF_CLK_RCV_EN_MASK; -+ val |= FIELD_PREP(CMA_REF_CLK_RCV_EN_MASK, CMA_REF_CLK_RCV_EN); -+ cdns_phy_reg_write(cdns_phy, PHY_PMA_CMN_CTRL1, val); -+ -+ /* PHY Registers */ -+ val = cdns_phy_reg_read(cdns_phy, PHY_PMA_CMN_CTRL1); -+ val &= ~CMA_REF_CLK_DIG_DIV_MASK; -+ val |= FIELD_PREP(CMA_REF_CLK_DIG_DIV_MASK, CMN_REF_CLK_DIG_DIV); -+ cdns_phy_reg_write(cdns_phy, PHY_PMA_CMN_CTRL1, val); -+ -+ val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL); -+ val &= ~PLL_DATA_RATE_CLK_DIV_MASK; -+ val |= FIELD_PREP(PLL_DATA_RATE_CLK_DIV_MASK, -+ PLL_DATA_RATE_CLK_DIV_HBR2); -+ cdns_phy_reg_write(cdns_phy, PHY_HDP_CLK_CTL, val); -+ -+ /* Common control module control and diagnostic registers */ -+ val = cdns_phy_reg_read(cdns_phy, CMN_CDIAG_REFCLK_CTRL); -+ val &= ~DIG_REF_CLK_DIV_SCALER_MASK; -+ val |= FIELD_PREP(DIG_REF_CLK_DIV_SCALER_MASK, REF_CLK_DIVIDER_SCALER); -+ val |= REFCLK_TERMINATION_EN_OVERRIDE_EN | REFCLK_TERMINATION_EN_OVERRIDE; -+ cdns_phy_reg_write(cdns_phy, CMN_CDIAG_REFCLK_CTRL, val); -+ -+ /* High speed clock used */ -+ val = cdns_phy_reg_read(cdns_phy, CMN_DIAG_HSCLK_SEL); -+ val &= ~(HSCLK1_SEL_MASK | HSCLK0_SEL_MASK); -+ val |= FIELD_PREP(HSCLK1_SEL_MASK, (p_ctrl_table->cmnda_hs_clk_1_sel >> 1)); -+ val |= FIELD_PREP(HSCLK0_SEL_MASK, (p_ctrl_table->cmnda_hs_clk_0_sel >> 1)); -+ cdns_phy_reg_write(cdns_phy, CMN_DIAG_HSCLK_SEL, val); -+ -+ for (k = 0; k < num_lanes; k++) { -+ val = cdns_phy_reg_read(cdns_phy, (XCVR_DIAG_HSCLK_SEL | (k << 9))); -+ val &= ~HSCLK_SEL_MODE3_MASK; -+ val |= FIELD_PREP(HSCLK_SEL_MODE3_MASK, -+ (p_ctrl_table->cmnda_hs_clk_0_sel >> 1)); -+ cdns_phy_reg_write(cdns_phy, (XCVR_DIAG_HSCLK_SEL | (k << 9)), val); -+ } -+ -+ /* PLL 0 control state machine registers */ -+ val = p_ctrl_table->vco_ring_select << 12; -+ cdns_phy_reg_write(cdns_phy, CMN_PLLSM0_USER_DEF_CTRL, val); -+ -+ if (pclk_in) { -+ val = 0x30a0; -+ } else { -+ val = cdns_phy_reg_read(cdns_phy, CMN_PLL0_VCOCAL_START); -+ val &= ~VCO_CALIB_CODE_START_POINT_VAL_MASK; -+ val |= FIELD_PREP(VCO_CALIB_CODE_START_POINT_VAL_MASK, -+ p_pll_table->vco_cal_code); -+ } -+ cdns_phy_reg_write(cdns_phy, CMN_PLL0_VCOCAL_START, val); -+ -+ cdns_phy_reg_write(cdns_phy, CMN_PLL0_VCOCAL_INIT_TMR, 0x0064); -+ cdns_phy_reg_write(cdns_phy, CMN_PLL0_VCOCAL_ITER_TMR, 0x000a); -+ -+ /* Common functions control and diagnostics registers */ -+ val = p_ctrl_table->cmnda_pll0_hs_sym_div_sel << 8; -+ val |= p_ctrl_table->cmnda_pll0_ip_div; -+ cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_INCLK_CTRL, val); -+ -+ cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_OVRD, 0x0000); -+ -+ val = p_ctrl_table->cmnda_pll0_fb_div_high; -+ val |= PLL_FEEDBACK_DIV_HI_OVERRIDE_EN; -+ cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_FBH_OVRD, val); -+ -+ val = p_ctrl_table->cmnda_pll0_fb_div_low; -+ val |= PLL_FEEDBACK_DIV_LO_OVERRIDE_EN; -+ cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_FBL_OVRD, val); -+ -+ if (!pclk_in) { -+ val = p_ctrl_table->cmnda_pll0_pxdiv_low; -+ cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_PXL_DIVL, val); -+ -+ val = p_ctrl_table->cmnda_pll0_pxdiv_high; -+ val |= PLL_PCLK_DIV_EN; -+ cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_PXL_DIVH, val); -+ } -+ -+ val = p_pll_table->volt_to_current_coarse; -+ val |= (p_pll_table->volt_to_current) << 4; -+ cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_V2I_TUNE, val); -+ -+ val = p_pll_table->charge_pump_gain; -+ cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_CP_TUNE, val); -+ -+ cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_LF_PROG, 0x0008); -+ -+ val = p_pll_table->pmos_ctrl; -+ val |= (p_pll_table->ndac_ctrl) << 8; -+ cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_PTATIS_TUNE1, val); -+ -+ val = p_pll_table->ptat_ndac_ctrl; -+ cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_PTATIS_TUNE2, val); -+ -+ if (pclk_in) -+ cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_TEST_MODE, 0x0022); -+ else -+ cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_TEST_MODE, 0x0020); -+ -+ cdns_phy_reg_write(cdns_phy, CMN_PSM_CLK_CTRL, 0x0016); -+ -+ /* Transceiver control and diagnostic registers */ -+ for (k = 0; k < num_lanes; k++) { -+ val = cdns_phy_reg_read(cdns_phy, (XCVR_DIAG_PLLDRC_CTRL | (k << 9))); -+ val &= ~DPLL_CLK_SEL_MODE3; -+ cdns_phy_reg_write(cdns_phy, (XCVR_DIAG_PLLDRC_CTRL | (k << 9)), val); -+ } -+ -+ for (k = 0; k < num_lanes; k++) { -+ val = cdns_phy_reg_read(cdns_phy, (TX_DIAG_TX_CTRL | (k << 9))); -+ val &= ~TX_IF_SUBRATE_MODE3_MASK; -+ val |= FIELD_PREP(TX_IF_SUBRATE_MODE3_MASK, -+ (p_ctrl_table->hsclk_div_tx_sub_rate >> 1)); -+ cdns_phy_reg_write(cdns_phy, (TX_DIAG_TX_CTRL | (k << 9)), val); -+ } -+ -+ val = cdns_phy_reg_read(cdns_phy, PHY_PMA_CMN_CTRL1); -+ val &= ~CMA_REF_CLK_SEL_MASK; -+ /* -+ * single ended reference clock (val |= 0x0030); -+ * differential clock (val |= 0x0000); -+ * for differential clock on the refclk_p and -+ * refclk_m off chip pins: CMN_DIAG_ACYA[8]=1'b1 -+ * cdns_phy_reg_write(cdns_phy, CMN_DIAG_ACYA, 0x0100); -+ */ -+ val |= FIELD_PREP(CMA_REF_CLK_SEL_MASK, 3); -+ cdns_phy_reg_write(cdns_phy, PHY_PMA_CMN_CTRL1, val); -+ -+ /* Deassert PHY reset */ -+ cdns_phy_reg_write(cdns_phy, PHY_ISO_CMN_CTRL, 0x0001); -+ cdns_phy_reg_write(cdns_phy, PHY_PMA_ISO_CMN_CTRL, 0x0003); -+ -+ /* Power state machine registers */ -+ for (k = 0; k < num_lanes; k++) -+ cdns_phy_reg_write(cdns_phy, XCVR_PSM_RCTRL | (k << 9), 0xfefc); -+ -+ /* Assert cmn_macro_pwr_en */ -+ cdns_phy_reg_write(cdns_phy, PHY_PMA_ISO_CMN_CTRL, 0x0013); -+ -+ /* wait for cmn_macro_pwr_en_ack */ -+ ret = wait_for_ack(cdns_phy, PHY_PMA_ISO_CMN_CTRL, CMN_MACRO_PWR_EN_ACK, -+ "MA output macro power up failed"); -+ if (ret < 0) -+ return ret; -+ -+ /* wait for cmn_ready */ -+ ret = wait_for_ack(cdns_phy, PHY_PMA_CMN_CTRL1, CMN_READY, -+ "PMA output ready failed"); -+ if (ret < 0) -+ return ret; -+ -+ for (k = 0; k < num_lanes; k++) { -+ cdns_phy_reg_write(cdns_phy, TX_PSC_A0 | (k << 9), 0x6791); -+ cdns_phy_reg_write(cdns_phy, TX_PSC_A1 | (k << 9), 0x6790); -+ cdns_phy_reg_write(cdns_phy, TX_PSC_A2 | (k << 9), 0x0090); -+ cdns_phy_reg_write(cdns_phy, TX_PSC_A3 | (k << 9), 0x0090); -+ -+ val = cdns_phy_reg_read(cdns_phy, RX_PSC_CAL | (k << 9)); -+ val &= 0xffbb; -+ cdns_phy_reg_write(cdns_phy, RX_PSC_CAL | (k << 9), val); -+ -+ val = cdns_phy_reg_read(cdns_phy, RX_PSC_A0 | (k << 9)); -+ val &= 0xffbb; -+ cdns_phy_reg_write(cdns_phy, RX_PSC_A0 | (k << 9), val); -+ } -+ -+ return 0; -+} -+ -+static int hdptx_hdmi_phy_cfg(struct cdns_hdptx_phy *cdns_phy, unsigned long long char_rate) -+{ -+ const struct hdptx_hdmi_ctrl *p_ctrl_table; -+ const struct hdptx_hdmi_pll_tuning *p_pll_table; -+ const u32 refclk_freq_khz = cdns_phy->ref_clk_rate / 1000; -+ const bool pclk_in = false; -+ u32 char_rate_khz = char_rate / 1000; -+ u32 vco_freq, rate; -+ u32 div_total, i; -+ -+ dev_dbg(cdns_phy->dev, "character clock: %d KHz\n ", char_rate_khz); -+ -+ /* Get right row from the ctrl_table table. -+ * check the character rate. -+ */ -+ for (i = 0; i < ARRAY_SIZE(pixel_clk_output_ctrl_table); i++) { -+ rate = pixel_clk_output_ctrl_table[i].feedback_factor * -+ pixel_clk_output_ctrl_table[i].pixel_clk_freq / 1000; -+ if (char_rate_khz == rate) { -+ p_ctrl_table = &pixel_clk_output_ctrl_table[i]; -+ break; -+ } -+ } -+ if (i == ARRAY_SIZE(pixel_clk_output_ctrl_table)) { -+ dev_warn(cdns_phy->dev, -+ "char clk (%d KHz) not supported\n", char_rate_khz); -+ return -EINVAL; -+ } -+ -+ div_total = p_ctrl_table->pll_fb_div_total; -+ vco_freq = refclk_freq_khz * div_total / p_ctrl_table->cmnda_pll0_ip_div; -+ -+ /* Get right row from the pixel_clk_output_pll_table table. -+ * Check if vco_freq_khz and feedback_div_total -+ * column matching with pixel_clk_output_pll_table. -+ */ -+ for (i = 0; i < ARRAY_SIZE(pixel_clk_output_pll_table); i++) { -+ if (vco_freq == pixel_clk_output_pll_table[i].vco_freq && -+ div_total == pixel_clk_output_pll_table[i].feedback_div_total) { -+ p_pll_table = &pixel_clk_output_pll_table[i]; -+ break; -+ } -+ } -+ if (i == ARRAY_SIZE(pixel_clk_output_pll_table)) { -+ dev_warn(cdns_phy->dev, "VCO (%d KHz) not supported\n", vco_freq); -+ return -EINVAL; -+ } -+ dev_dbg(cdns_phy->dev, "VCO frequency is (%d KHz)\n", vco_freq); -+ -+ return hdptx_hdmi_phy_config(cdns_phy, p_ctrl_table, p_pll_table, pclk_in); -+} -+ -+static int hdptx_hdmi_phy_power_up(struct cdns_hdptx_phy *cdns_phy) -+{ -+ int ret; -+ -+ /* set Power State to A2 */ -+ cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A2); -+ -+ cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_0, 1); -+ cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_1, 1); -+ cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_2, 1); -+ cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_3, 1); -+ -+ ret = wait_for_ack(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A2_ACK, -+ "Wait A2 Ack failed"); -+ if (ret < 0) -+ return ret; -+ -+ /* Power up ARC */ -+ hdptx_hdmi_arc_config(cdns_phy); -+ -+ /* Configure PHY in A0 mode (PHY must be in the A0 power -+ * state in order to transmit data) -+ */ -+ cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A0); -+ -+ return wait_for_ack(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A0_ACK, -+ "Wait A0 Ack failed"); -+} -+ -+static int hdptx_hdmi_phy_power_down(struct cdns_hdptx_phy *cdns_phy) -+{ -+ u32 val; -+ -+ val = cdns_phy_reg_read(cdns_phy, PHY_HDP_MODE_CTRL); -+ val &= ~(POWER_STATE_A0 | POWER_STATE_A1 | POWER_STATE_A2 | POWER_STATE_A3); -+ /* PHY_DP_MODE_CTL set to A3 power state */ -+ cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL, val | POWER_STATE_A3); -+ -+ return wait_for_ack(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A3_ACK, -+ "Wait A3 Ack failed"); -+} -+ -+static int hdptx_hdmi_configure(struct phy *phy, -+ union phy_configure_opts *opts) -+{ -+ struct cdns_hdptx_phy *cdns_phy = phy_get_drvdata(phy); -+ u32 reg; -+ int ret; -+ -+ cdns_phy->hdmi.tmds_char_rate = opts->hdmi.tmds_char_rate; -+ -+ /* Check HDMI FW alive before HDMI PHY init */ -+ ret = readl_poll_timeout(cdns_phy->regs + KEEP_ALIVE, reg, -+ reg & CDNS_KEEP_ALIVE_MASK, 500, -+ CDNS_KEEP_ALIVE_TIMEOUT); -+ if (ret < 0) { -+ dev_err(cdns_phy->dev, "NO HDMI FW running\n"); -+ return -ENXIO; -+ } -+ -+ /* Configure PHY */ -+ if (hdptx_hdmi_phy_cfg(cdns_phy, cdns_phy->hdmi.tmds_char_rate) < 0) { -+ dev_err(cdns_phy->dev, "failed to set phy pclock\n"); -+ return -EINVAL; -+ } -+ -+ hdptx_hdmi_phy_set_vswing(cdns_phy); -+ -+ return 0; -+} -+ -+static int cdns_hdptx_phy_on(struct phy *phy) -+{ -+ struct cdns_hdptx_phy *cdns_phy = phy_get_drvdata(phy); -+ -+ if (phy->attrs.mode == PHY_MODE_DP) -+ return hdptx_dp_phy_power_up(cdns_phy); -+ else -+ return hdptx_hdmi_phy_power_up(cdns_phy); -+} -+ -+static int cdns_hdptx_phy_off(struct phy *phy) -+{ -+ struct cdns_hdptx_phy *cdns_phy = phy_get_drvdata(phy); -+ -+ if (phy->attrs.mode == PHY_MODE_DP) -+ return hdptx_dp_phy_power_down(cdns_phy); -+ else -+ return hdptx_hdmi_phy_power_down(cdns_phy); -+} -+ -+static int -+cdns_hdptx_phy_valid(struct phy *phy, enum phy_mode mode, -+ int submode, union phy_configure_opts *opts) -+{ -+ u32 rate = opts->hdmi.tmds_char_rate / 1000; -+ int i; -+ -+ if (mode == PHY_MODE_DP) -+ return 0; -+ -+ for (i = 0; i < ARRAY_SIZE(pixel_clk_output_ctrl_table); i++) -+ if (rate == pixel_clk_output_ctrl_table[i].pixel_clk_freq) -+ return 0; -+ -+ return -EINVAL; -+} -+ -+static int cdns_hdptx_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode) -+{ -+ struct cdns_hdptx_phy *cdns_phy = phy_get_drvdata(phy); -+ int ret = 0; -+ -+ if (mode == PHY_MODE_DP) { -+ hdptx_dp_phy_ref_clock_type(cdns_phy); -+ hdptx_dp_aux_cfg(cdns_phy); -+ } else if (mode != PHY_MODE_HDMI) { -+ dev_err(&phy->dev, "Invalid PHY mode: %u\n", mode); -+ return -EINVAL; -+ } -+ -+ return ret; -+} -+ -+static int cdns_hdptx_configure(struct phy *phy, -+ union phy_configure_opts *opts) -+{ -+ if (phy->attrs.mode == PHY_MODE_DP) -+ return hdptx_dp_configure(phy, opts); -+ else -+ return hdptx_hdmi_configure(phy, opts); -+} -+ -+static const struct phy_ops cdns_hdptx_phy_ops = { -+ .set_mode = cdns_hdptx_phy_set_mode, -+ .configure = cdns_hdptx_configure, -+ .power_on = cdns_hdptx_phy_on, -+ .power_off = cdns_hdptx_phy_off, -+ .validate = cdns_hdptx_phy_valid, -+ .owner = THIS_MODULE, -+}; -+ -+static int cdns_hdptx_phy_probe(struct platform_device *pdev) -+{ -+ struct cdns_hdptx_phy *cdns_phy; -+ struct device *dev = &pdev->dev; -+ struct device_node *node = dev->of_node; -+ struct phy_provider *phy_provider; -+ struct resource *res; -+ struct phy *phy; -+ int ret; -+ -+ cdns_phy = devm_kzalloc(dev, sizeof(*cdns_phy), GFP_KERNEL); -+ if (!cdns_phy) -+ return -ENOMEM; -+ -+ dev_set_drvdata(dev, cdns_phy); -+ cdns_phy->dev = dev; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) -+ return -ENODEV; -+ cdns_phy->regs = devm_ioremap(dev, res->start, resource_size(res)); -+ if (IS_ERR(cdns_phy->regs)) -+ return PTR_ERR(cdns_phy->regs); -+ -+ phy = devm_phy_create(dev, node, &cdns_hdptx_phy_ops); -+ if (IS_ERR(phy)) -+ return PTR_ERR(phy); -+ -+ cdns_phy->phy = phy; -+ phy_set_drvdata(phy, cdns_phy); -+ -+ /* init base struct for access mhdp mailbox */ -+ cdns_phy->base.dev = cdns_phy->dev; -+ cdns_phy->base.regs = cdns_phy->regs; -+ -+ ret = hdptx_clk_enable(cdns_phy); -+ if (ret) { -+ dev_err(dev, "Init clk fail\n"); -+ return -EINVAL; -+ } -+ -+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); -+ if (IS_ERR(phy_provider)) -+ return PTR_ERR(phy_provider); -+ -+ return 0; -+} -+ -+static const struct of_device_id cdns_hdptx_phy_of_match[] = { -+ {.compatible = "fsl,imx8mq-hdptx-phy" }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, cdns_hdptx_phy_of_match); -+ -+static struct platform_driver cdns_hdptx_phy_driver = { -+ .probe = cdns_hdptx_phy_probe, -+ .driver = { -+ .name = "cdns-hdptx-phy", -+ .of_match_table = cdns_hdptx_phy_of_match, -+ } -+}; -+module_platform_driver(cdns_hdptx_phy_driver); -+ -+MODULE_AUTHOR("Sandor Yu <sandor.yu@nxp.com>"); -+MODULE_DESCRIPTION("Cadence HDP-TX DP/HDMI PHY driver"); -+MODULE_LICENSE("GPL"); --- -2.34.1 - -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH v19 7/8] arm64: dts: imx8mq: Add DCSS + HDMI/DP display - pipeline -From: Alexander Stein <alexander.stein@ew.tq-group.com> -Date: Tue, 26 Nov 2024 22:11:52 +0800 -Message-Id: <d5fe3953ce13aa7e068190291d94c213302f8109.1732627815.git.Sandor.yu@nxp.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -This adds DCSS + MHDP + MHDP PHY nodes. PHY mode (DP/HDMI) is selected -by the connector type connected to mhdp port@1 endpoint. - -Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com> ---- -v17->v19: - *No change - - arch/arm64/boot/dts/freescale/imx8mq.dtsi | 68 +++++++++++++++++++++++ - 1 file changed, 68 insertions(+) - -diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi -index d51de8d899b2b..df8ba1d5391ae 100644 ---- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi -+++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi -@@ -1602,6 +1602,74 @@ aips4: bus@32c00000 { /* AIPS4 */ - #size-cells = <1>; - ranges = <0x32c00000 0x32c00000 0x400000>; - -+ mdhp_phy: phy@32c00000 { -+ compatible = "fsl,imx8mq-hdptx-phy"; -+ reg = <0x32c00000 0x100000>; -+ #phy-cells = <0>; -+ clocks = <&hdmi_phy_27m>, <&clk IMX8MQ_CLK_DISP_APB_ROOT>; -+ clock-names = "ref", "apb"; -+ }; -+ -+ mhdp: bridge@32c00000 { -+ compatible = "fsl,imx8mq-mhdp8501"; -+ reg = <0x32c00000 0x100000>; -+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>, -+ <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>; -+ interrupt-names = "plug_in", "plug_out"; -+ clocks = <&clk IMX8MQ_CLK_DISP_APB_ROOT>; -+ phys = <&mdhp_phy>; -+ status = "disabled"; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ port@0 { -+ reg = <0>; -+ -+ mhdp_in: endpoint { -+ remote-endpoint = <&dcss_out>; -+ }; -+ }; -+ -+ port@1 { -+ reg = <1>; -+ -+ mhdp_out: endpoint { -+ }; -+ }; -+ }; -+ }; -+ -+ dcss: display-controller@32e00000 { -+ compatible = "nxp,imx8mq-dcss"; -+ reg = <0x32e00000 0x2d000>, <0x32e2f000 0x1000>; -+ interrupt-parent = <&irqsteer>; -+ interrupts = <6>, <8>, <9>; -+ interrupt-names = "ctxld", "ctxld_kick", "vblank"; -+ clocks = <&clk IMX8MQ_CLK_DISP_APB_ROOT>, -+ <&clk IMX8MQ_CLK_DISP_AXI_ROOT>, -+ <&clk IMX8MQ_CLK_DISP_RTRM_ROOT>, -+ <&clk IMX8MQ_VIDEO2_PLL_OUT>, -+ <&clk IMX8MQ_CLK_DISP_DTRC>; -+ clock-names = "apb", "axi", "rtrm", "pix", "dtrc"; -+ assigned-clocks = <&clk IMX8MQ_CLK_DISP_AXI>, -+ <&clk IMX8MQ_CLK_DISP_RTRM>, -+ <&clk IMX8MQ_VIDEO2_PLL1_REF_SEL>; -+ assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_800M>, -+ <&clk IMX8MQ_SYS1_PLL_800M>, -+ <&clk IMX8MQ_CLK_27M>; -+ assigned-clock-rates = <800000000>, -+ <400000000>; -+ status = "disabled"; -+ -+ port { -+ dcss_out: endpoint { -+ remote-endpoint = <&mhdp_in>; -+ }; -+ }; -+ }; -+ - irqsteer: interrupt-controller@32e2d000 { - compatible = "fsl,imx8m-irqsteer", "fsl,imx-irqsteer"; - reg = <0x32e2d000 0x1000>; --- -2.34.1 - -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH v19 8/8] arm64: dts: imx8mq: tqma8mq-mba8mx: Enable HDMI - support -From: Alexander Stein <alexander.stein@ew.tq-group.com> -Date: Tue, 26 Nov 2024 22:11:53 +0800 -Message-Id: <ae6f043294e1d34c2473d657bb01ff967b85ef0d.1732627815.git.Sandor.yu@nxp.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -Add HDMI connector and connect it to MHDP output. Enable peripherals -for HDMI output. - -Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com> ---- -v18->v19: -- Move property data-lanes to endpoint of port@1 - -v17->v18: -- replace lane-mapping with data-lanes - - .../dts/freescale/imx8mq-tqma8mq-mba8mx.dts | 26 +++++++++++++++++++ - arch/arm64/boot/dts/freescale/mba8mx.dtsi | 11 ++++++++ - 2 files changed, 37 insertions(+) - -diff --git a/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dts b/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dts -index 0165f3a259853..5ba06a411c6a1 100644 ---- a/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dts -+++ b/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dts -@@ -53,6 +53,10 @@ &btn2 { - gpios = <&gpio3 17 GPIO_ACTIVE_LOW>; - }; - -+&dcss { -+ status = "okay"; -+}; -+ - &gpio_leds { - led3 { - label = "led3"; -@@ -60,6 +64,14 @@ led3 { - }; - }; - -+&hdmi_connector { -+ port { -+ hdmi_connector_in: endpoint { -+ remote-endpoint = <&mhdp_out>; -+ }; -+ }; -+}; -+ - &i2c1 { - expander2: gpio@25 { - compatible = "nxp,pca9555"; -@@ -91,6 +103,20 @@ &led2 { - gpios = <&gpio3 16 GPIO_ACTIVE_HIGH>; - }; - -+&mhdp { -+ status = "okay"; -+ ports { -+ port@1 { -+ reg = <1>; -+ -+ mhdp_out: endpoint { -+ remote-endpoint = <&hdmi_connector_in>; -+ data-lanes = <0 1 2 3>; -+ }; -+ }; -+ }; -+}; -+ - /* PCIe slot on X36 */ - &pcie0 { - reset-gpio = <&expander0 14 GPIO_ACTIVE_LOW>; -diff --git a/arch/arm64/boot/dts/freescale/mba8mx.dtsi b/arch/arm64/boot/dts/freescale/mba8mx.dtsi -index 58e3865c28895..d04b75a76dfe6 100644 ---- a/arch/arm64/boot/dts/freescale/mba8mx.dtsi -+++ b/arch/arm64/boot/dts/freescale/mba8mx.dtsi -@@ -89,6 +89,17 @@ gpio_delays: gpio-delays { - gpio-line-names = "LVDS_BRIDGE_EN_1V8"; - }; - -+ hdmi_connector: connector { -+ compatible = "hdmi-connector"; -+ label = "X11"; -+ type = "a"; -+ -+ port { -+ hdmi_connector_in: endpoint { -+ }; -+ }; -+ }; -+ - panel: panel-lvds { - /* - * Display is not fixed, so compatible has to be added from --- -2.34.1 - diff --git a/gnu/packages/patches/reform/ls1028a-mnt-reform2/0000-dtsi-add-hdptx.patch b/gnu/packages/patches/reform/ls1028a-mnt-reform2/0000-dtsi-add-hdptx.patch deleted file mode 100644 index fce52fbfe6..0000000000 --- a/gnu/packages/patches/reform/ls1028a-mnt-reform2/0000-dtsi-add-hdptx.patch +++ /dev/null @@ -1,32 +0,0 @@ ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -@@ -871,8 +871,28 @@ - arm,malidp-arqos-value = <0xd000d000>; - - port { -- dpi0_out: endpoint { -+ dpi0_out: endpoint { -+ remote-endpoint = <&dp1_out>; -+ }; -+ }; -+ }; - -+ hdptx0: display@f200000 { -+ compatible = "cdn,ls1028a-dp"; -+ reg = <0x0 0xf200000 0x0 0xfffff>; -+ interrupts = <0 221 IRQ_TYPE_LEVEL_HIGH>; -+ clocks = <&clockgen QORIQ_CLK_HWACCEL 2>, <&clockgen QORIQ_CLK_HWACCEL 2>, -+ <&clockgen QORIQ_CLK_HWACCEL 2>, <&clockgen QORIQ_CLK_HWACCEL 2>, -+ <&clockgen QORIQ_CLK_HWACCEL 2>, <&dpclk>; -+ clock-names = "clk_core", "pclk", "sclk", -+ "cclk", "clk_vif", "clk_pxl"; -+ lane-mapping = <0x4e>; -+ edp_num_lanes = <0x2>; -+ firmware-name = "ls1028a-mhdpfw.bin"; -+ -+ port { -+ dp1_out: endpoint { -+ remote-endpoint = <&dpi0_out>; - }; - }; - }; diff --git a/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-pocket-reform/0001-a311d-viu-fifo-lines-config.patch b/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-pocket-reform/0001-a311d-viu-fifo-lines-config.patch deleted file mode 100644 index 3adc093178..0000000000 --- a/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-pocket-reform/0001-a311d-viu-fifo-lines-config.patch +++ /dev/null @@ -1,20 +0,0 @@ -diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c -index cb67496..20d4cbc 100644 ---- a/drivers/gpu/drm/meson/meson_drv.c -+++ b/drivers/gpu/drm/meson/meson_drv.c -@@ -300,6 +300,15 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) - - /* Hardware Initialization */ - -+ // temporary workaround for different vertical offsets (wraparound) -+ // on different MNT Reform family display panels -+ // until a proper fix is found -+ priv->viu.hold_fifo_lines = 31; -+ if (of_property_present(dev->of_node, "viu-hold-fifo-lines")) { -+ of_property_read_u32(dev->of_node, "viu-hold-fifo-lines", &priv->viu.hold_fifo_lines); -+ dev_warn(drm->dev, "viu-hold-fifo-lines from device tree: %d\n", priv->viu.hold_fifo_lines); -+ } -+ - meson_vpu_init(priv); - meson_venc_init(priv); - meson_vpp_init(priv); diff --git a/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-pocket-reform/0002-a311d-viu-fifo-lines-config-header.patch b/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-pocket-reform/0002-a311d-viu-fifo-lines-config-header.patch deleted file mode 100644 index 6dfcecb60b..0000000000 --- a/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-pocket-reform/0002-a311d-viu-fifo-lines-config-header.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff --git a/drivers/gpu/drm/meson/meson_drv.h b/drivers/gpu/drm/meson/meson_drv.h -index 3f9345c..5d88d10 100644 ---- a/drivers/gpu/drm/meson/meson_drv.h -+++ b/drivers/gpu/drm/meson/meson_drv.h -@@ -154,6 +154,7 @@ struct meson_drm { - uint32_t vpp_hsc_phase_ctrl; - uint32_t vpp_blend_vd2_h_start_end; - uint32_t vpp_blend_vd2_v_start_end; -+ uint32_t hold_fifo_lines; - } viu; - - struct { diff --git a/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-pocket-reform/0003-tlv320aic31xx-add-1228800hz-support.patch b/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-pocket-reform/0003-tlv320aic31xx-add-1228800hz-support.patch deleted file mode 100644 index c9cd058c70..0000000000 --- a/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-pocket-reform/0003-tlv320aic31xx-add-1228800hz-support.patch +++ /dev/null @@ -1,96 +0,0 @@ -commit 49eb7d2f225e00742f9c95a796fd781c93465ca6 -Author: Lukas F. Hartmann <lukas@mntre.com> -Date: Mon Feb 26 23:05:15 2024 +0100 - - tlv320aic31xx: add 12.288MHz mclk support and fix formatting - - Original numbers from https://patchwork.amarulasolutions.com/patch/1742/ - Thus: - - Co-authored-by: Anthony Brandon <anthony@amarulasolutions.com> - -diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c -index 9611aa8..c506a80 100644 ---- a/sound/soc/codecs/tlv320aic31xx.c -+++ b/sound/soc/codecs/tlv320aic31xx.c -@@ -200,65 +200,76 @@ static const struct aic31xx_rate_divs aic31xx_divs[] = { - { 512000, 8000, 4, 48, 0, 128, 48, 2, 128, 48, 2}, - {12000000, 8000, 1, 8, 1920, 128, 48, 2, 128, 48, 2}, - {12000000, 8000, 1, 8, 1920, 128, 32, 3, 128, 32, 3}, -+ {12288000, 8000, 1, 8, 0, 128, 48, 2, 128, 48, 2}, - {12500000, 8000, 1, 7, 8643, 128, 48, 2, 128, 48, 2}, - /* 11.025k rate */ - { 705600, 11025, 3, 48, 0, 128, 24, 3, 128, 24, 3}, - {12000000, 11025, 1, 7, 5264, 128, 32, 2, 128, 32, 2}, - {12000000, 11025, 1, 8, 4672, 128, 24, 3, 128, 24, 3}, -+ {12288000, 11025, 1, 7, 3500, 128, 32, 2, 128, 32, 2}, - {12500000, 11025, 1, 7, 2253, 128, 32, 2, 128, 32, 2}, - /* 16k rate */ - { 512000, 16000, 4, 48, 0, 128, 16, 3, 128, 16, 3}, - { 1024000, 16000, 2, 48, 0, 128, 16, 3, 128, 16, 3}, - {12000000, 16000, 1, 8, 1920, 128, 24, 2, 128, 24, 2}, - {12000000, 16000, 1, 8, 1920, 128, 16, 3, 128, 16, 3}, -+ {12288000, 16000, 1, 8, 0, 128, 24, 2, 128, 24, 2}, - {12500000, 16000, 1, 7, 8643, 128, 24, 2, 128, 24, 2}, - /* 22.05k rate */ - { 705600, 22050, 4, 36, 0, 128, 12, 3, 128, 12, 3}, - { 1411200, 22050, 2, 36, 0, 128, 12, 3, 128, 12, 3}, - {12000000, 22050, 1, 7, 5264, 128, 16, 2, 128, 16, 2}, - {12000000, 22050, 1, 8, 4672, 128, 12, 3, 128, 12, 3}, -+ {12288000, 22050, 1, 7, 3500, 128, 16, 2, 128, 16, 2}, - {12500000, 22050, 1, 7, 2253, 128, 16, 2, 128, 16, 2}, - /* 32k rate */ -- { 1024000, 32000, 2, 48, 0, 128, 12, 2, 128, 12, 2}, -- { 2048000, 32000, 1, 48, 0, 128, 12, 2, 128, 12, 2}, -+ { 1024000, 32000, 2, 48, 0, 128, 12, 2, 128, 12, 2}, -+ { 2048000, 32000, 1, 48, 0, 128, 12, 2, 128, 12, 2}, - {12000000, 32000, 1, 8, 1920, 128, 12, 2, 128, 12, 2}, - {12000000, 32000, 1, 8, 1920, 128, 8, 3, 128, 8, 3}, -+ {12288000, 32000, 1, 8, 0, 128, 12, 2, 128, 12, 2}, - {12500000, 32000, 1, 7, 8643, 128, 12, 2, 128, 12, 2}, - /* 44.1k rate */ - { 1411200, 44100, 2, 32, 0, 128, 8, 2, 128, 8, 2}, - { 2822400, 44100, 1, 32, 0, 128, 8, 2, 128, 8, 2}, - {12000000, 44100, 1, 7, 5264, 128, 8, 2, 128, 8, 2}, - {12000000, 44100, 1, 8, 4672, 128, 6, 3, 128, 6, 3}, -+ {12288000, 44100, 1, 7, 3500, 128, 8, 2, 128, 8, 2}, - {12500000, 44100, 1, 7, 2253, 128, 8, 2, 128, 8, 2}, - /* 48k rate */ - { 1536000, 48000, 2, 32, 0, 128, 8, 2, 128, 8, 2}, - { 3072000, 48000, 1, 32, 0, 128, 8, 2, 128, 8, 2}, - {12000000, 48000, 1, 8, 1920, 128, 8, 2, 128, 8, 2}, - {12000000, 48000, 1, 7, 6800, 96, 5, 4, 96, 5, 4}, -+ {12288000, 48000, 1, 8, 0, 128, 8, 2, 128, 8, 2}, - {12500000, 48000, 1, 7, 8643, 128, 8, 2, 128, 8, 2}, - /* 88.2k rate */ - { 2822400, 88200, 2, 16, 0, 64, 8, 2, 64, 8, 2}, - { 5644800, 88200, 1, 16, 0, 64, 8, 2, 64, 8, 2}, - {12000000, 88200, 1, 7, 5264, 64, 8, 2, 64, 8, 2}, - {12000000, 88200, 1, 8, 4672, 64, 6, 3, 64, 6, 3}, -+ {12288000, 88200, 1, 7, 3500, 64, 8, 2, 64, 8, 2}, - {12500000, 88200, 1, 7, 2253, 64, 8, 2, 64, 8, 2}, - /* 96k rate */ - { 3072000, 96000, 2, 16, 0, 64, 8, 2, 64, 8, 2}, - { 6144000, 96000, 1, 16, 0, 64, 8, 2, 64, 8, 2}, - {12000000, 96000, 1, 8, 1920, 64, 8, 2, 64, 8, 2}, - {12000000, 96000, 1, 7, 6800, 48, 5, 4, 48, 5, 4}, -+ {12288000, 96000, 1, 8, 0, 64, 8, 2, 64, 8, 2}, - {12500000, 96000, 1, 7, 8643, 64, 8, 2, 64, 8, 2}, - /* 176.4k rate */ - { 5644800, 176400, 2, 8, 0, 32, 8, 2, 32, 8, 2}, - {11289600, 176400, 1, 8, 0, 32, 8, 2, 32, 8, 2}, - {12000000, 176400, 1, 7, 5264, 32, 8, 2, 32, 8, 2}, - {12000000, 176400, 1, 8, 4672, 32, 6, 3, 32, 6, 3}, -+ {12288000, 176400, 1, 7, 3500, 32, 8, 2, 32, 8, 2}, - {12500000, 176400, 1, 7, 2253, 32, 8, 2, 32, 8, 2}, - /* 192k rate */ -- { 6144000, 192000, 2, 8, 0, 32, 8, 2, 32, 8, 2}, -- {12288000, 192000, 1, 8, 0, 32, 8, 2, 32, 8, 2}, -+ { 6144000, 192000, 2, 8, 0, 32, 8, 2, 32, 8, 2}, -+ {12288000, 192000, 1, 8, 0, 32, 8, 2, 32, 8, 2}, - {12000000, 192000, 1, 8, 1920, 32, 8, 2, 32, 8, 2}, - {12000000, 192000, 1, 7, 6800, 24, 5, 4, 24, 5, 4}, -+ {12288000, 192000, 1, 8, 0, 32, 8, 2, 32, 8, 2}, - {12500000, 192000, 1, 7, 8643, 32, 8, 2, 32, 8, 2}, - }; - diff --git a/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0001-Revert-drm-bridge-synopsys-dw-mipi-dsi-enable-EoTp-b.patch b/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0001-Revert-drm-bridge-synopsys-dw-mipi-dsi-enable-EoTp-b.patch deleted file mode 100644 index 56d4165ddc..0000000000 --- a/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0001-Revert-drm-bridge-synopsys-dw-mipi-dsi-enable-EoTp-b.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 62de193d8150578bf040bfee65db4bf0cf834cee Mon Sep 17 00:00:00 2001 -From: Johannes Schauer Marin Rodrigues <josch@mister-muffin.de> -Date: Sat, 21 Dec 2024 17:54:09 +0100 -Subject: [PATCH] Revert "drm/bridge: synopsys: dw-mipi-dsi: enable EoTp by - default" - -This reverts commit d97e71e449373efbd2403f1d7a32d416599f32ac. ---- - drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 7 +------ - 1 file changed, 1 insertion(+), 6 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c -index 0fb02e4e7f4e..c4e9d96933dc 100644 ---- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c -+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c -@@ -722,12 +722,7 @@ static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi, - - static void dw_mipi_dsi_packet_handler_config(struct dw_mipi_dsi *dsi) - { -- u32 val = CRC_RX_EN | ECC_RX_EN | BTA_EN | EOTP_TX_EN; -- -- if (dsi->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET) -- val &= ~EOTP_TX_EN; -- -- dsi_write(dsi, DSI_PCKHDL_CFG, val); -+ dsi_write(dsi, DSI_PCKHDL_CFG, CRC_RX_EN | ECC_RX_EN | BTA_EN); - } - - static void dw_mipi_dsi_video_packet_config(struct dw_mipi_dsi *dsi, --- -2.39.5 - diff --git a/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0011-dw-mipi-dsi-phy-stop-wait-time.patch b/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0011-dw-mipi-dsi-phy-stop-wait-time.patch deleted file mode 100644 index 3941afb5ed..0000000000 --- a/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0011-dw-mipi-dsi-phy-stop-wait-time.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 573d769372d0dd1b6e7199048764cd851a511750 Mon Sep 17 00:00:00 2001 -From: "Lukas F. Hartmann" <lukas@mntre.com> -Date: Sun, 9 Jul 2023 23:02:47 +0200 -Subject: [PATCH 11/21] dw-mipi-dsi-phy-stop-wait-time - ---- - drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - ---- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c -+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c -@@ -605,8 +605,10 @@ static void dw_mipi_dsi_video_mode_confi - */ - val = ENABLE_LOW_POWER; - -- if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) -+ if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) { - val |= VID_MODE_TYPE_BURST; -+ printk(KERN_ALERT "DEBUG: dw-mipi-dsi VID_MODE_TYPE_BURST\n"); -+ } - else if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) - val |= VID_MODE_TYPE_NON_BURST_SYNC_PULSES; - else -@@ -886,7 +888,7 @@ static void dw_mipi_dsi_dphy_interface_c - * stop wait time should be the maximum between host dsi - * and panel stop wait times - */ -- dsi_write(dsi, DSI_PHY_IF_CFG, PHY_STOP_WAIT_TIME(0x20) | -+ dsi_write(dsi, DSI_PHY_IF_CFG, PHY_STOP_WAIT_TIME(0x1) | - N_LANES(dsi->lanes)); - } - diff --git a/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0012-innolux-n125hce-gn1-timing-tweaks.patch b/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0012-innolux-n125hce-gn1-timing-tweaks.patch deleted file mode 100644 index 17e38143b5..0000000000 --- a/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0012-innolux-n125hce-gn1-timing-tweaks.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 6a51b0b4e1bae07da42ab82c41628c5ca1997c6f Mon Sep 17 00:00:00 2001 -From: "Lukas F. Hartmann" <lukas@mntre.com> -Date: Sun, 9 Jul 2023 23:02:48 +0200 -Subject: [PATCH 12/21] innolux-n125hce-gn1-timing-tweaks - ---- - drivers/gpu/drm/panel/panel-edp.c | 32 +++++++++++++++++++++++++++++++ - 1 file changed, 32 insertions(+) - ---- a/drivers/gpu/drm/panel/panel-edp.c -+++ b/drivers/gpu/drm/panel/panel-edp.c -@@ -1318,6 +1318,35 @@ static const struct panel_desc innolux_n - }, - }; - -+static const struct drm_display_mode innolux_n125hce_gn1_a311d_mode = { -+ //.clock = 162000, 70Hz -+ // wrong colors are only if this mismatches dtb assigned clock -+ .clock = 156000, // 68Hz -+ //.clock = 153600, // 65Hz (921.6mhz) -+ //.clock = 138780, // 59Hz (832.68mhz) -+ //.clock = 138780, // 59Hz (832.68mhz) -+ .hdisplay = 1920, -+ .hsync_start = 1920 + 40, -+ .hsync_end = 1920 + 40 + 40, -+ .htotal = 1920 + 40 + 40 + 80, -+ .vdisplay = 1080, -+ // a311d mipi dsi driver currently calculates these wrongly, -+ // so we have to work around that here -+ .vsync_start = 1080 + 1, -+ .vsync_end = 1080 + 1 + 4, -+ .vtotal = 1080 + 1 + 4 + 27, -+}; -+ -+static const struct panel_desc innolux_n125hce_gn1_a311d = { -+ .modes = &innolux_n125hce_gn1_a311d_mode, -+ .num_modes = 1, -+ .bpc = 8, -+ .size = { -+ .width = 276, -+ .height = 155, -+ }, -+}; -+ - static const struct drm_display_mode innolux_p120zdg_bf1_mode = { - .clock = 206016, - .hdisplay = 2160, -@@ -1736,6 +1765,9 @@ static const struct of_device_id platfor - .compatible = "innolux,n125hce-gn1", - .data = &innolux_n125hce_gn1, - }, { -+ .compatible = "innolux,n125hce-gn1-a311d", -+ .data = &innolux_n125hce_gn1_a311d, -+ }, { - .compatible = "innolux,p120zdg-bf1", - .data = &innolux_p120zdg_bf1, - }, { diff --git a/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0013-meson-viu-hold-fifo-lines.patch b/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0013-meson-viu-hold-fifo-lines.patch deleted file mode 100644 index d255d20214..0000000000 --- a/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0013-meson-viu-hold-fifo-lines.patch +++ /dev/null @@ -1,25 +0,0 @@ -From f45675995ec2fab90adec43426039dd6ffda94a7 Mon Sep 17 00:00:00 2001 -From: "Lukas F. Hartmann" <lukas@mntre.com> -Date: Sun, 9 Jul 2023 23:02:49 +0200 -Subject: [PATCH 13/21] meson-viu-hold-fifo-lines - ---- - drivers/gpu/drm/meson/meson_viu.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/meson/meson_viu.c b/drivers/gpu/drm/meson/meson_viu.c -index cd399b0b7..119d00f23 100644 ---- a/drivers/gpu/drm/meson/meson_viu.c -+++ b/drivers/gpu/drm/meson/meson_viu.c -@@ -441,7 +441,7 @@ void meson_viu_init(struct meson_drm *priv) - VIU_OSD_FIFO_LIMITS(2); /* fifo_lim: 2*16=32 */ - - if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) -- reg |= (VIU_OSD_BURST_LENGTH_32 | VIU_OSD_HOLD_FIFO_LINES(31)); -+ reg |= (VIU_OSD_BURST_LENGTH_32 | VIU_OSD_HOLD_FIFO_LINES(4)); // FIXME altered - else - reg |= (VIU_OSD_BURST_LENGTH_64 | VIU_OSD_HOLD_FIFO_LINES(4)); - --- -2.40.0 - diff --git a/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0014-meson-venc-sync.patch.patch b/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0014-meson-venc-sync.patch.patch deleted file mode 100644 index bfece0535b..0000000000 --- a/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0014-meson-venc-sync.patch.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 46a66919ef279bace11147d89c373bc4440a6d5a Mon Sep 17 00:00:00 2001 -From: "Lukas F. Hartmann" <lukas@mntre.com> -Date: Sun, 9 Jul 2023 23:02:50 +0200 -Subject: [PATCH 14/21] meson-venc-sync.patch - ---- - drivers/gpu/drm/meson/meson_venc.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c -index 3bf0d6e4f..0e9a9bb07 100644 ---- a/drivers/gpu/drm/meson/meson_venc.c -+++ b/drivers/gpu/drm/meson/meson_venc.c -@@ -1711,7 +1711,7 @@ void meson_venc_mipi_dsi_mode_set(struct meson_drm *priv, - writel_relaxed(vavon_eline, priv->io_base + _REG(L_OEV1_VE_ADDR)); - - /* Hsync signal for TTL */ -- if (mode->flags & DRM_MODE_FLAG_PHSYNC) { -+ if (mode->flags & DRM_MODE_FLAG_NHSYNC) { - writel_relaxed(hso_begin, priv->io_base + _REG(L_STH1_HS_ADDR)); - writel_relaxed(hso_end, priv->io_base + _REG(L_STH1_HE_ADDR)); - } else { -@@ -1724,7 +1724,7 @@ void meson_venc_mipi_dsi_mode_set(struct meson_drm *priv, - /* Vsync signal for TTL */ - writel_relaxed(vso_begin, priv->io_base + _REG(L_STV1_HS_ADDR)); - writel_relaxed(vso_end, priv->io_base + _REG(L_STV1_HE_ADDR)); -- if (mode->flags & DRM_MODE_FLAG_PVSYNC) { -+ if (mode->flags & DRM_MODE_FLAG_NVSYNC) { - writel_relaxed(vso_bline, priv->io_base + _REG(L_STV1_VS_ADDR)); - writel_relaxed(vso_eline, priv->io_base + _REG(L_STV1_VE_ADDR)); - } else { --- -2.40.0 - diff --git a/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0015-meson-dw-mipi-dsi-sync-invert.patch b/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0015-meson-dw-mipi-dsi-sync-invert.patch deleted file mode 100644 index 434371b032..0000000000 --- a/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0015-meson-dw-mipi-dsi-sync-invert.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 55cc68c56db6bb4b27bb7e52d63d37172dbfb51b Mon Sep 17 00:00:00 2001 -From: "Lukas F. Hartmann" <lukas@mntre.com> -Date: Sun, 9 Jul 2023 23:02:51 +0200 -Subject: [PATCH 15/21] meson-dw-mipi-dsi-sync-invert - ---- - drivers/gpu/drm/meson/meson_dw_mipi_dsi.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - ---- a/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c -+++ b/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c -@@ -129,7 +129,9 @@ static int dw_mipi_dsi_phy_init(void *pr - FIELD_PREP(MIPI_DSI_TOP_IN_COLOR_MODE, venc_data_width) | - FIELD_PREP(MIPI_DSI_TOP_COMP2_SEL, 2) | - FIELD_PREP(MIPI_DSI_TOP_COMP1_SEL, 1) | -- FIELD_PREP(MIPI_DSI_TOP_COMP0_SEL, 0), -+ FIELD_PREP(MIPI_DSI_TOP_COMP0_SEL, 0) | -+ (mipi_dsi->mode->flags & DRM_MODE_FLAG_NHSYNC ? 0 : MIPI_DSI_TOP_HSYNC_INVERT) | -+ (mipi_dsi->mode->flags & DRM_MODE_FLAG_NVSYNC ? 0 : MIPI_DSI_TOP_VSYNC_INVERT), - mipi_dsi->base + MIPI_DSI_TOP_CNTL); - - return phy_configure(mipi_dsi->phy, &mipi_dsi->phy_opts); diff --git a/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0016-sn65dsi86-burst-mode-support.patch b/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0016-sn65dsi86-burst-mode-support.patch deleted file mode 100644 index 2f4b19349e..0000000000 --- a/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0016-sn65dsi86-burst-mode-support.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 6d6b45ed6cdf1ed5c2efcd05019cea4a1df0a962 Mon Sep 17 00:00:00 2001 -From: "Lukas F. Hartmann" <lukas@mntre.com> -Date: Sun, 9 Jul 2023 23:02:51 +0200 -Subject: [PATCH 16/21] sn65dsi86-burst-mode-support - ---- - drivers/gpu/drm/bridge/ti-sn65dsi86.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c -+++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c -@@ -722,6 +722,10 @@ static int ti_sn_attach_host(struct auxi - dsi->lanes = 4; - dsi->format = MIPI_DSI_FMT_RGB888; - dsi->mode_flags = MIPI_DSI_MODE_VIDEO; -+ if (of_property_read_bool(pdata->dev->of_node, "burst-mode")) { -+ dsi->mode_flags |= MIPI_DSI_MODE_VIDEO_BURST; -+ printk(KERN_ALERT "DEBUG ti_sn65dsi86: burst mode enabled\n"); -+ }; - - /* For i.MX8MP / Samsung DSIM Host, don't guess the HS rate, but read it from DTS */ - if (of_device_is_compatible(pdata->host_node, "fsl,imx8mp-mipi-dsim")) { diff --git a/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0018-sn65dsi86-never-turn-off.patch b/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0018-sn65dsi86-never-turn-off.patch deleted file mode 100644 index f54dd6ec07..0000000000 --- a/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0018-sn65dsi86-never-turn-off.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 87c72ab5cd34dfa5fe1c91c475e5b6d4b8e1aad6 Mon Sep 17 00:00:00 2001 -From: "Lukas F. Hartmann" <lukas@mntre.com> -Date: Sun, 17 Sep 2023 17:43:10 +0200 -Subject: [PATCH 18/21] sn65dsi86-never-turn-off - ---- - drivers/gpu/drm/bridge/ti-sn65dsi86.c | 15 +++++++++++++++ - 1 file changed, 15 insertions(+) - ---- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c -+++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c -@@ -347,6 +347,9 @@ static void ti_sn65dsi86_disable_comms(s - { - mutex_lock(&pdata->comms_mutex); - -+ printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ return; -+ - pdata->comms_enabled = false; - clk_disable_unprepare(pdata->refclk); - -@@ -387,6 +390,9 @@ static int __maybe_unused ti_sn65dsi86_s - struct ti_sn65dsi86 *pdata = dev_get_drvdata(dev); - int ret; - -+ printk(KERN_ALERT "DEBUG: ti_sn65dsi86_suspend skipped.\n"); -+ return 0; -+ - if (pdata->refclk) - ti_sn65dsi86_disable_comms(pdata); - -@@ -820,6 +826,9 @@ static void ti_sn_bridge_atomic_disable( - { - struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge); - -+ printk(KERN_ALERT "DEBUG: ti_sn_bridge_atomic_disable skipped.\n"); -+ return; -+ - /* disable video stream */ - regmap_update_bits(pdata->regmap, SN_ENH_FRAME_REG, VSTREAM_ENABLE, 0); - } -@@ -1185,6 +1194,9 @@ static void ti_sn_bridge_atomic_post_dis - { - struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge); - -+ printk(KERN_ALERT "DEBUG: ti_sn_bridge_atomic_post_disable skipped.\n"); -+ return; -+ - /* semi auto link training mode OFF */ - regmap_write(pdata->regmap, SN_ML_TX_MODE_REG, 0); - /* Num lanes to 0 as per power sequencing in data sheet */ -@@ -1871,6 +1883,9 @@ static inline void ti_sn_gpio_unregister - - static void ti_sn65dsi86_runtime_disable(void *data) - { -+ printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ return; -+ - pm_runtime_dont_use_autosuspend(data); - pm_runtime_disable(data); - } diff --git a/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0020-LOCAL-ALSA-Assign-internal-PCM-chmap-ELD-IEC958-kctl.patch b/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0020-LOCAL-ALSA-Assign-internal-PCM-chmap-ELD-IEC958-kctl.patch deleted file mode 100644 index d333be4f64..0000000000 --- a/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0020-LOCAL-ALSA-Assign-internal-PCM-chmap-ELD-IEC958-kctl.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 2c1b731fb890ac217152a62ea524c2e7ee10e05e Mon Sep 17 00:00:00 2001 -From: Anssi Hannula <anssi.hannula@iki.fi> -Date: Sun, 17 Apr 2022 04:37:48 +0000 -Subject: [PATCH 20/21] LOCAL: ALSA: Assign internal PCM chmap/ELD/IEC958 kctls - to device 0 - -On SoC sound devices utilizing codec2codec DAI links with a HDMI codec -the kctls for chmap, ELD, IEC958 are currently created using the -internal PCM device numbers. This causes userspace to not see the -actual channel mapping. - -Affected devices include LibreTech LePotato and Wetek Play 2. - -The proper fix would be not create these kctls for internal PCMs and -instead create them for the real userspace-visible PCMs, somehow -forwarding the controls between the HDMI codec and the real PCM. - -As a workaround, simply use device=0 for all channel map controls and -SoC HDMI codec controls for internal PCM devices. - -Signed-off-by: Anssi Hannula <anssi.hannula@iki.fi> ---- - sound/core/pcm_lib.c | 5 ++++- - sound/soc/codecs/hdmi-codec.c | 3 ++- - 2 files changed, 6 insertions(+), 2 deletions(-) - ---- a/sound/core/pcm_lib.c -+++ b/sound/core/pcm_lib.c -@@ -2547,7 +2547,10 @@ int snd_pcm_add_chmap_ctls(struct snd_pc - knew.name = "Playback Channel Map"; - else - knew.name = "Capture Channel Map"; -- knew.device = pcm->device; -+ if (pcm->internal && pcm->device) -+ dev_info(pcm->card->dev, "workaround active: internal PCM chmap controls mapped to device 0\n"); -+ else -+ knew.device = pcm->device; - knew.count = pcm->streams[stream].substream_count; - knew.private_value = private_value; - info->kctl = snd_ctl_new1(&knew, info); ---- a/sound/soc/codecs/hdmi-codec.c -+++ b/sound/soc/codecs/hdmi-codec.c -@@ -801,7 +801,8 @@ static int hdmi_codec_pcm_new(struct snd - if (!kctl) - return -ENOMEM; - -- kctl->id.device = rtd->pcm->device; -+ if (!rtd->pcm->internal) -+ kctl->id.device = rtd->pcm->device; - ret = snd_ctl_add(rtd->card->snd_card, kctl); - if (ret < 0) - return ret; diff --git a/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0021-HACK-of-partial-revert-of-fdt.c-changes.patch b/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0021-HACK-of-partial-revert-of-fdt.c-changes.patch deleted file mode 100644 index 6949343199..0000000000 --- a/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0021-HACK-of-partial-revert-of-fdt.c-changes.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 25b84eeff0c5013366821e82654313d591609c57 Mon Sep 17 00:00:00 2001 -From: Stefan Agner <stefan@agner.ch> -Date: Wed, 15 Sep 2021 05:00:45 +0000 -Subject: [PATCH 21/21] HACK: of: partial revert of fdt.c changes - -This resolves reports similar to the below which are present in dmesg -since Linux 5.10; which are also causing crashes in some distros: - -[ 0.000000] OF: fdt: Reserved memory: failed to reserve memory for node 'secmon@5000000': base 0x0000000005000000, size 3 MiB - -Signed-off-by: Christian Hewitt <christianshewitt@gmail.com> ---- - drivers/of/fdt.c | 9 --------- - 1 file changed, 9 deletions(-) - ---- a/drivers/of/of_reserved_mem.c -+++ b/drivers/of/of_reserved_mem.c -@@ -82,15 +82,6 @@ static int __init early_init_dt_reserve_ - phys_addr_t size, bool nomap) - { - if (nomap) { -- /* -- * If the memory is already reserved (by another region), we -- * should not allow it to be marked nomap, but don't worry -- * if the region isn't memory as it won't be mapped. -- */ -- if (memblock_overlaps_region(&memblock.memory, base, size) && -- memblock_is_region_reserved(base, size)) -- return -EBUSY; -- - return memblock_mark_nomap(base, size); - } - return memblock_reserve(base, size); diff --git a/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0022-add-bt-and-eth-resets.patch b/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0022-add-bt-and-eth-resets.patch deleted file mode 100644 index a7d9176047..0000000000 --- a/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0022-add-bt-and-eth-resets.patch +++ /dev/null @@ -1,26 +0,0 @@ -diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-bananapi-cm4.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-bananapi-cm4.dtsi -index 97e5229..d1435a3 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-g12b-bananapi-cm4.dtsi -+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-bananapi-cm4.dtsi -@@ -211,6 +211,11 @@ ðmac { - pinctrl-names = "default"; - phy-mode = "rgmii-txid"; - phy-handle = <&external_phy>; -+ -+ /* This is only a partial fix; ethernet only works reliably after a reload -+ of the mdio, dwmac, stmmac etc modules */ -+ snps,reset-gpio = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>; -+ snps,reset-delays-us = <0 1000000 2000000>; - }; - - &frddr_a { -@@ -369,8 +374,7 @@ &uart_A { - - bluetooth { - compatible = "realtek,rtl8822cs-bt"; -- enable-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>; -- host-wake-gpios = <&gpio GPIOX_19 GPIO_ACTIVE_HIGH>; -+ enable-gpios = <&gpio GPIOX_19 GPIO_ACTIVE_HIGH>; - device-wake-gpios = <&gpio GPIOX_18 GPIO_ACTIVE_HIGH>; - }; - }; diff --git a/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0023-sdio-pullups.patch b/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0023-sdio-pullups.patch deleted file mode 100644 index c161f51b46..0000000000 --- a/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0023-sdio-pullups.patch +++ /dev/null @@ -1,28 +0,0 @@ ---- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi -+++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi -@@ -937,17 +937,22 @@ - }; - - sdio_pins: sdio { -- mux { -+ mux-0 { - groups = "sdio_d0", - "sdio_d1", - "sdio_d2", - "sdio_d3", -- "sdio_clk", - "sdio_cmd"; - function = "sdio"; -- bias-disable; -+ bias-pull-up; - drive-strength-microamp = <4000>; - }; -+ -+ mux-1 { -+ groups = "sdio_clk"; -+ function = "sdio"; -+ bias-disable; -+ }; - }; - - sdio_clk_gate_pins: sdio_clk_gate { diff --git a/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0024-sdio-improve-wifi-speed.patch b/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0024-sdio-improve-wifi-speed.patch deleted file mode 100644 index b0805ad2f0..0000000000 --- a/gnu/packages/patches/reform/meson-g12b-bananapi-cm4-mnt-reform2/0024-sdio-improve-wifi-speed.patch +++ /dev/null @@ -1,39 +0,0 @@ -diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-bananapi-cm4.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-bananapi-cm4.dtsi -index 5805bc9..144d68b 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-g12b-bananapi-cm4.dtsi -+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-bananapi-cm4.dtsi -@@ -31,6 +31,7 @@ sdio_pwrseq: sdio-pwrseq { - reset-gpios = <&gpio GPIOAO_6 GPIO_ACTIVE_LOW>; - clocks = <&wifi32k>; - clock-names = "ext_clock"; -+ post-power-on-delay-ms = <200>; - }; - - emmc_1v8: regulator-emmc-1v8 { -@@ -299,19 +300,24 @@ &sd_emmc_a { - #size-cells = <0>; - - bus-width = <4>; -+ cap-sd-highspeed; -+ sd-uhs-sdr50; - sd-uhs-sdr104; -- max-frequency = <50000000>; -+ max-frequency = <100000000>; - - non-removable; - disable-wp; - -+ /* apparently DRAM quirk is not needed on modern A311D chips */ -+ /delete-property/ amlogic,dram-access-quirk; -+ - /* WiFi firmware requires power in suspend */ - keep-power-in-suspend; - - mmc-pwrseq = <&sdio_pwrseq>; - - vmmc-supply = <&vddao_3v3>; -- vqmmc-supply = <&vddao_3v3>; -+ vqmmc-supply = <&vddao_1v8>; - - status = "okay"; - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0001-regulator-Add-of_regulator_get_optional-for-pure-DT-.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0001-regulator-Add-of_regulator_get_optional-for-pure-DT-.patch deleted file mode 100644 index 6200de6e88..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0001-regulator-Add-of_regulator_get_optional-for-pure-DT-.patch +++ /dev/null @@ -1,211 +0,0 @@ -From debd2a1b87a90b69e3669d9afeb8f06a5270c8b7 Mon Sep 17 00:00:00 2001 -From: Chen-Yu Tsai <wenst@chromium.org> -Date: Wed, 25 Sep 2024 17:38:04 +0800 -Subject: [PATCH 01/63] regulator: Add of_regulator_get_optional() for pure DT - regulator lookup - -The to-be-introduced I2C component prober needs to enable regulator -supplies (and toggle GPIO pins) for the various components it intends -to probe. To support this, a new "pure DT lookup" method for getting -regulator supplies is needed, since the device normally requesting -the supply won't get created until after the component is probed to -be available. - -Add a new of_regulator_get_optional() function for this. This mirrors -the existing regulator_get_optional() function, but is OF-specific. -The underlying code that supports the existing regulator_get*() -functions has been reworked in previous patches to support this -specific case. - -Also convert an existing usage of "dev && dev->of_node" to -"dev_of_node(dev)". - -Link: https://lore.kernel.org/all/20231220203537.83479-2-jernej.skrabec@gmail.com/ [1] -Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> -Link: https://patch.msgid.link/20240925093807.1026949-2-wenst@chromium.org -Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> -Signed-off-by: Mark Brown <broonie@kernel.org> ---- - drivers/regulator/core.c | 4 +-- - drivers/regulator/internal.h | 2 ++ - drivers/regulator/of_regulator.c | 51 ++++++++++++++++++++++++++---- - include/linux/regulator/consumer.h | 20 ++++++++++++ - 4 files changed, 69 insertions(+), 8 deletions(-) - -diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c -index 1179766811f5..d0b3879f2746 100644 ---- a/drivers/regulator/core.c -+++ b/drivers/regulator/core.c -@@ -1959,8 +1959,8 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev, - regulator_supply_alias(&dev, &supply); - - /* first do a dt based lookup */ -- if (dev && dev->of_node) { -- r = of_regulator_dev_lookup(dev, supply); -+ if (dev_of_node(dev)) { -+ r = of_regulator_dev_lookup(dev, dev_of_node(dev), supply); - if (!IS_ERR(r)) - return r; - if (PTR_ERR(r) == -EPROBE_DEFER) -diff --git a/drivers/regulator/internal.h b/drivers/regulator/internal.h -index 5b43f802468d..f62cacbbc729 100644 ---- a/drivers/regulator/internal.h -+++ b/drivers/regulator/internal.h -@@ -67,6 +67,7 @@ static inline struct regulator_dev *dev_to_rdev(struct device *dev) - - #ifdef CONFIG_OF - struct regulator_dev *of_regulator_dev_lookup(struct device *dev, -+ struct device_node *np, - const char *supply); - struct regulator_init_data *regulator_of_get_init_data(struct device *dev, - const struct regulator_desc *desc, -@@ -82,6 +83,7 @@ bool of_check_coupling_data(struct regulator_dev *rdev); - - #else - static inline struct regulator_dev *of_regulator_dev_lookup(struct device *dev, -+ struct device_node *np, - const char *supply) - { - return ERR_PTR(-ENODEV); -diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c -index 3f490d81abc2..358c3ed791db 100644 ---- a/drivers/regulator/of_regulator.c -+++ b/drivers/regulator/of_regulator.c -@@ -588,7 +588,8 @@ static struct device_node *of_get_child_regulator(struct device_node *parent, - - /** - * of_get_regulator - get a regulator device node based on supply name -- * @dev: Device pointer for the consumer (of regulator) device -+ * @dev: Device pointer for dev_printk() messages -+ * @node: Device node pointer for supply property lookup - * @supply: regulator supply name - * - * Extract the regulator device node corresponding to the supply name. -@@ -596,15 +597,16 @@ static struct device_node *of_get_child_regulator(struct device_node *parent, - * Return: Pointer to the &struct device_node corresponding to the regulator - * if found, or %NULL if not found. - */ --static struct device_node *of_get_regulator(struct device *dev, const char *supply) -+static struct device_node *of_get_regulator(struct device *dev, struct device_node *node, -+ const char *supply) - { - struct device_node *regnode = NULL; - char prop_name[64]; /* 64 is max size of property name */ - -- dev_dbg(dev, "Looking up %s-supply from device tree\n", supply); -+ dev_dbg(dev, "Looking up %s-supply from device node %pOF\n", supply, node); - - snprintf(prop_name, 64, "%s-supply", supply); -- regnode = of_parse_phandle(dev->of_node, prop_name, 0); -+ regnode = of_parse_phandle(node, prop_name, 0); - if (regnode) - return regnode; - -@@ -628,6 +630,7 @@ static struct regulator_dev *of_find_regulator_by_node(struct device_node *np) - /** - * of_regulator_dev_lookup - lookup a regulator device with device tree only - * @dev: Device pointer for regulator supply lookup. -+ * @np: Device node pointer for regulator supply lookup. - * @supply: Supply name or regulator ID. - * - * Return: Pointer to the &struct regulator_dev on success, or ERR_PTR() -@@ -642,13 +645,13 @@ static struct regulator_dev *of_find_regulator_by_node(struct device_node *np) - * * -%ENODEV if lookup fails permanently. - * * -%EPROBE_DEFER if lookup could succeed in the future. - */ --struct regulator_dev *of_regulator_dev_lookup(struct device *dev, -+struct regulator_dev *of_regulator_dev_lookup(struct device *dev, struct device_node *np, - const char *supply) - { - struct regulator_dev *r; - struct device_node *node; - -- node = of_get_regulator(dev, supply); -+ node = of_get_regulator(dev, np, supply); - if (node) { - r = of_find_regulator_by_node(node); - of_node_put(node); -@@ -665,6 +668,42 @@ struct regulator_dev *of_regulator_dev_lookup(struct device *dev, - return ERR_PTR(-ENODEV); - } - -+static struct regulator *_of_regulator_get(struct device *dev, struct device_node *node, -+ const char *id, enum regulator_get_type get_type) -+{ -+ struct regulator_dev *r; -+ int ret; -+ -+ ret = _regulator_get_common_check(dev, id, get_type); -+ if (ret) -+ return ERR_PTR(ret); -+ -+ r = of_regulator_dev_lookup(dev, node, id); -+ return _regulator_get_common(r, dev, id, get_type); -+} -+ -+/** -+ * of_regulator_get_optional - get optional regulator via device tree lookup -+ * @dev: device used for dev_printk() messages -+ * @node: device node for regulator "consumer" -+ * @id: Supply name -+ * -+ * Return: pointer to struct regulator corresponding to the regulator producer, -+ * or PTR_ERR() encoded error number. -+ * -+ * This is intended for use by consumers that want to get a regulator -+ * supply directly from a device node, and can and want to deal with -+ * absence of such supplies. This will _not_ consider supply aliases. -+ * See regulator_dev_lookup(). -+ */ -+struct regulator *of_regulator_get_optional(struct device *dev, -+ struct device_node *node, -+ const char *id) -+{ -+ return _of_regulator_get(dev, node, id, OPTIONAL_GET); -+} -+EXPORT_SYMBOL_GPL(of_regulator_get_optional); -+ - /* - * Returns number of regulators coupled with rdev. - */ -diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h -index b9ce521910a0..2b22f07e491c 100644 ---- a/include/linux/regulator/consumer.h -+++ b/include/linux/regulator/consumer.h -@@ -168,6 +168,19 @@ int devm_regulator_get_enable_read_voltage(struct device *dev, const char *id); - void regulator_put(struct regulator *regulator); - void devm_regulator_put(struct regulator *regulator); - -+#if IS_ENABLED(CONFIG_OF) -+struct regulator *__must_check of_regulator_get_optional(struct device *dev, -+ struct device_node *node, -+ const char *id); -+#else -+static inline struct regulator *__must_check of_regulator_get_optional(struct device *dev, -+ struct device_node *node, -+ const char *id) -+{ -+ return ERR_PTR(-ENODEV); -+} -+#endif -+ - int regulator_register_supply_alias(struct device *dev, const char *id, - struct device *alias_dev, - const char *alias_id); -@@ -350,6 +363,13 @@ devm_regulator_get_optional(struct device *dev, const char *id) - return ERR_PTR(-ENODEV); - } - -+static inline struct regulator *__must_check of_regulator_get_optional(struct device *dev, -+ struct device_node *node, -+ const char *id) -+{ -+ return ERR_PTR(-ENODEV); -+} -+ - static inline void regulator_put(struct regulator *regulator) - { - } --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0001-scripts-package-builddeb-allow-hooks-also-in-usr-sha.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0001-scripts-package-builddeb-allow-hooks-also-in-usr-sha.patch deleted file mode 100644 index 093c48cba1..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0001-scripts-package-builddeb-allow-hooks-also-in-usr-sha.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 2c0854790dd4b72b691f72e59ade824ff6176d07 Mon Sep 17 00:00:00 2001 -From: Johannes Schauer Marin Rodrigues <josch@mister-muffin.de> -Date: Wed, 27 Nov 2024 10:22:50 +0100 -Subject: [PATCH] scripts/package/builddeb: allow hooks also in - /usr/share/kernel - -By passing an additional directory to run-parts, allow Debian and its -derivatives to ship maintainer scripts in /usr while at the same time -allowing the local admin to override or disable them by placing hooks of -the same name in /etc. This adds support for the mechanism described in -the UAPI Configuration Files Specification for kernel hooks. The same -idea is also used by udev, systemd or modprobe for their config files. -https://uapi-group.org/specifications/specs/configuration_files_specification/ - -This functionality relies on run-parts 5.21 or later. It is the -responsibility of packages installing hooks into /usr/share/kernel to -also declare a Depends: debianutils (>= 5.21). - -KDEB_HOOKDIR can be used to change the list of directories that is -searched. By default, /etc/kernel and /usr/share/kernel are hook -directories. - -Signed-off-by: Johannes Schauer Marin Rodrigues <josch@mister-muffin.de> ---- - scripts/package/builddeb | 33 +++++++++++++++++++++++++-------- - 1 file changed, 25 insertions(+), 8 deletions(-) - -diff --git a/scripts/package/builddeb b/scripts/package/builddeb -index 441b0bb66e0d..6e83f6f3ec6d 100755 ---- a/scripts/package/builddeb -+++ b/scripts/package/builddeb -@@ -5,10 +5,12 @@ - # - # Simple script to generate a deb package for a Linux kernel. All the - # complexity of what to do with a kernel after it is installed or removed --# is left to other scripts and packages: they can install scripts in the --# /etc/kernel/{pre,post}{inst,rm}.d/ directories (or an alternative location --# specified in KDEB_HOOKDIR) that will be called on package install and --# removal. -+# is left to other scripts and packages. Scripts can be placed into the -+# preinst, postinst, prerm and postrm directories in /etc/kernel or -+# /usr/share/kernel. A different list of search directories can be given -+# via KDEB_HOOKDIR. Scripts in directories earlier in the list will -+# override scripts of the same name in later directories. The script will -+# be called on package installation and removal. - - set -eu - -@@ -68,11 +70,18 @@ install_linux_image () { - # kernel packages, as well as kernel packages built using make-kpkg. - # make-kpkg sets $INITRD to indicate whether an initramfs is wanted, and - # so do we; recent versions of dracut and initramfs-tools will obey this. -- debhookdir=${KDEB_HOOKDIR:-/etc/kernel} -+ debhookdir=${KDEB_HOOKDIR:-/etc/kernel /usr/share/kernel} -+ -+ # Only pre-create the first hook directory. Support for more than one hook -+ # directory requires run-parts 5.21 and it is the responsibility of packages -+ # creating additional hook directories to declare that dependency. -+ firsthookdir=${debhookdir%% *} - for script in postinst postrm preinst prerm; do -- mkdir -p "${pdir}${debhookdir}/${script}.d" -+ mkdir -p "${pdir}${firsthookdir}/${script}.d" -+ done - -- mkdir -p "${pdir}/DEBIAN" -+ mkdir -p "${pdir}/DEBIAN" -+ for script in postinst postrm preinst prerm; do - cat <<-EOF > "${pdir}/DEBIAN/${script}" - #!/bin/sh - -@@ -84,7 +93,15 @@ install_linux_image () { - # Tell initramfs builder whether it's wanted - export INITRD=$(if_enabled_echo CONFIG_BLK_DEV_INITRD Yes No) - -- test -d ${debhookdir}/${script}.d && run-parts --arg="${KERNELRELEASE}" --arg="/${installed_image_path}" ${debhookdir}/${script}.d -+ # run-parts will error out if one of its directory arguments does not -+ # exist, so filter the list of hook directories accordingly. -+ hookdirs= -+ for dir in ${debhookdir}; do -+ test -d "\$dir/${script}.d" || continue -+ hookdirs="\$hookdirs \$dir/${script}.d" -+ done -+ hookdirs="\${hookdirs# }" -+ test -n "\$hookdirs" && run-parts --arg="${KERNELRELEASE}" --arg="/${installed_image_path}" \$hookdirs - exit 0 - EOF - chmod 755 "${pdir}/DEBIAN/${script}" --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0002-regulator-Add-devres-version-of-of_regulator_get_opt.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0002-regulator-Add-devres-version-of-of_regulator_get_opt.patch deleted file mode 100644 index b44218865f..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0002-regulator-Add-devres-version-of-of_regulator_get_opt.patch +++ /dev/null @@ -1,175 +0,0 @@ -From 10faa718fd7252c2f603b66ac2a8d0d49d038577 Mon Sep 17 00:00:00 2001 -From: Chen-Yu Tsai <wenst@chromium.org> -Date: Wed, 25 Sep 2024 17:38:05 +0800 -Subject: [PATCH 02/63] regulator: Add devres version of - of_regulator_get_optional() - -There are existing uses for a devres version of of_regulator_get_optional() -in power domain drivers. On MediaTek platforms, power domains may have -regulator supplies tied to them. The driver currently tries to use -devm_regulator_get() to not have to manage the lifecycle, but ends up -doing it in a very hacky way by replacing the device node of the power -domain controller device to the device node of the power domain that is -currently being registered, getting the supply, and reverting the device -node. - -Provide a better API so that the hack can be replaced. - -Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> -Link: https://patch.msgid.link/20240925093807.1026949-3-wenst@chromium.org -Signed-off-by: Mark Brown <broonie@kernel.org> ---- - drivers/regulator/devres.c | 39 ++++++++++++++++++++++++++++++ - drivers/regulator/internal.h | 16 +++++++----- - drivers/regulator/of_regulator.c | 4 +-- - include/linux/regulator/consumer.h | 17 +++++++++++++ - 4 files changed, 68 insertions(+), 8 deletions(-) - -diff --git a/drivers/regulator/devres.c b/drivers/regulator/devres.c -index 1b893cdd1aad..36164aec30e8 100644 ---- a/drivers/regulator/devres.c -+++ b/drivers/regulator/devres.c -@@ -749,3 +749,42 @@ void *devm_regulator_irq_helper(struct device *dev, - return ptr; - } - EXPORT_SYMBOL_GPL(devm_regulator_irq_helper); -+ -+#if IS_ENABLED(CONFIG_OF) -+static struct regulator *_devm_of_regulator_get(struct device *dev, struct device_node *node, -+ const char *id, int get_type) -+{ -+ struct regulator **ptr, *regulator; -+ -+ ptr = devres_alloc(devm_regulator_release, sizeof(*ptr), GFP_KERNEL); -+ if (!ptr) -+ return ERR_PTR(-ENOMEM); -+ -+ regulator = _of_regulator_get(dev, node, id, get_type); -+ if (!IS_ERR(regulator)) { -+ *ptr = regulator; -+ devres_add(dev, ptr); -+ } else { -+ devres_free(ptr); -+ } -+ -+ return regulator; -+} -+ -+/** -+ * devm_of_regulator_get_optional - Resource managed of_regulator_get_optional() -+ * @dev: device used for dev_printk() messages and resource lifetime management -+ * @node: device node for regulator "consumer" -+ * @id: supply name or regulator ID. -+ * -+ * Managed regulator_get_optional(). Regulators returned from this -+ * function are automatically regulator_put() on driver detach. See -+ * of_regulator_get_optional() for more information. -+ */ -+struct regulator *devm_of_regulator_get_optional(struct device *dev, struct device_node *node, -+ const char *id) -+{ -+ return _devm_of_regulator_get(dev, node, id, OPTIONAL_GET); -+} -+EXPORT_SYMBOL_GPL(devm_of_regulator_get_optional); -+#endif -diff --git a/drivers/regulator/internal.h b/drivers/regulator/internal.h -index f62cacbbc729..b3d48dc38bc4 100644 ---- a/drivers/regulator/internal.h -+++ b/drivers/regulator/internal.h -@@ -65,6 +65,13 @@ static inline struct regulator_dev *dev_to_rdev(struct device *dev) - return container_of(dev, struct regulator_dev, dev); - } - -+enum regulator_get_type { -+ NORMAL_GET, -+ EXCLUSIVE_GET, -+ OPTIONAL_GET, -+ MAX_GET_TYPE -+}; -+ - #ifdef CONFIG_OF - struct regulator_dev *of_regulator_dev_lookup(struct device *dev, - struct device_node *np, -@@ -74,6 +81,9 @@ struct regulator_init_data *regulator_of_get_init_data(struct device *dev, - struct regulator_config *config, - struct device_node **node); - -+struct regulator *_of_regulator_get(struct device *dev, struct device_node *node, -+ const char *id, enum regulator_get_type get_type); -+ - struct regulator_dev *of_parse_coupled_regulator(struct regulator_dev *rdev, - int index); - -@@ -116,12 +126,6 @@ static inline bool of_check_coupling_data(struct regulator_dev *rdev) - } - - #endif --enum regulator_get_type { -- NORMAL_GET, -- EXCLUSIVE_GET, -- OPTIONAL_GET, -- MAX_GET_TYPE --}; - - int _regulator_get_common_check(struct device *dev, const char *id, - enum regulator_get_type get_type); -diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c -index 358c3ed791db..3d85762beda6 100644 ---- a/drivers/regulator/of_regulator.c -+++ b/drivers/regulator/of_regulator.c -@@ -668,8 +668,8 @@ struct regulator_dev *of_regulator_dev_lookup(struct device *dev, struct device_ - return ERR_PTR(-ENODEV); - } - --static struct regulator *_of_regulator_get(struct device *dev, struct device_node *node, -- const char *id, enum regulator_get_type get_type) -+struct regulator *_of_regulator_get(struct device *dev, struct device_node *node, -+ const char *id, enum regulator_get_type get_type) - { - struct regulator_dev *r; - int ret; -diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h -index 2b22f07e491c..8c3c372ad735 100644 ---- a/include/linux/regulator/consumer.h -+++ b/include/linux/regulator/consumer.h -@@ -172,6 +172,9 @@ void devm_regulator_put(struct regulator *regulator); - struct regulator *__must_check of_regulator_get_optional(struct device *dev, - struct device_node *node, - const char *id); -+struct regulator *__must_check devm_of_regulator_get_optional(struct device *dev, -+ struct device_node *node, -+ const char *id); - #else - static inline struct regulator *__must_check of_regulator_get_optional(struct device *dev, - struct device_node *node, -@@ -179,6 +182,13 @@ static inline struct regulator *__must_check of_regulator_get_optional(struct de - { - return ERR_PTR(-ENODEV); - } -+ -+static inline struct regulator *__must_check devm_of_regulator_get_optional(struct device *dev, -+ struct device_node *node, -+ const char *id) -+{ -+ return ERR_PTR(-ENODEV); -+} - #endif - - int regulator_register_supply_alias(struct device *dev, const char *id, -@@ -370,6 +380,13 @@ static inline struct regulator *__must_check of_regulator_get_optional(struct de - return ERR_PTR(-ENODEV); - } - -+static inline struct regulator *__must_check devm_of_regulator_get_optional(struct device *dev, -+ struct device_node *node, -+ const char *id) -+{ -+ return ERR_PTR(-ENODEV); -+} -+ - static inline void regulator_put(struct regulator *regulator) - { - } --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0004-arm64-dts-rockchip-rk3588-rock5b-add-USB-C-support.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0004-arm64-dts-rockchip-rk3588-rock5b-add-USB-C-support.patch deleted file mode 100644 index b16af3afcc..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0004-arm64-dts-rockchip-rk3588-rock5b-add-USB-C-support.patch +++ /dev/null @@ -1,213 +0,0 @@ -From 80e6ea31bfc9eebf480fe97b4b0c8c1f1c892ab1 Mon Sep 17 00:00:00 2001 -From: Sebastian Reichel <sebastian.reichel@collabora.com> -Date: Tue, 25 Jul 2023 18:35:56 +0200 -Subject: [PATCH 04/63] arm64: dts: rockchip: rk3588-rock5b: add USB-C support - -Add hardware description for the USB-C port in the Radxa Rock 5 Model B. -This describes the OHCI, EHCI and XHCI USB parts, but not yet the -DisplayPort AltMode (bindings are not yet upstream). - -For now the fusb302 node is marked with status "fail", since the board -is usually powered through the USB-C port. Handling of errors can result -in hard resets, which removed the bus power for some time resulting in -a board reset. - -The main problem right now is that devices are supposed to interact with -the power-supply within 5 seconds after the plug event according to the -USB PD specification. This is more or less impossible to achieve when -the kernel is the first software communicating with the power-supply. - -Currently the most likely workaround will be USB-PD handling added to -U-Boot. In that case U-Boot can update the status to "okay". That way -booting a kernel with the updated DT on an old U-Boot avoids a reset -loop. - -Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> ---- - .../boot/dts/rockchip/rk3588-rock-5b.dts | 121 ++++++++++++++++++ - 1 file changed, 121 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts -index 6bd06e46a101..aed327526853 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts -@@ -4,6 +4,7 @@ - - #include <dt-bindings/gpio/gpio.h> - #include <dt-bindings/leds/common.h> -+#include <dt-bindings/usb/pd.h> - #include "rk3588.dtsi" - - / { -@@ -72,6 +73,15 @@ rfkill-bt { - shutdown-gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>; - }; - -+ vcc12v_dcin: vcc12v-dcin-regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc12v_dcin"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <12000000>; -+ regulator-max-microvolt = <12000000>; -+ }; -+ - vcc3v3_pcie2x1l0: vcc3v3-pcie2x1l0-regulator { - compatible = "regulator-fixed"; - enable-active-high; -@@ -130,6 +140,7 @@ vcc5v0_sys: vcc5v0-sys-regulator { - regulator-boot-on; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; -+ vin-supply = <&vcc12v_dcin>; - }; - - vcc_1v1_nldo_s3: vcc-1v1-nldo-s3-regulator { -@@ -232,6 +243,67 @@ regulator-state-mem { - }; - }; - -+&i2c4 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c4m1_xfer>; -+ status = "okay"; -+ -+ usbc0: usb-typec@22 { -+ compatible = "fcs,fusb302"; -+ reg = <0x22>; -+ interrupt-parent = <&gpio3>; -+ interrupts = <RK_PB4 IRQ_TYPE_LEVEL_LOW>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&usbc0_int>; -+ vbus-supply = <&vcc12v_dcin>; -+ /* -+ * When the board is starting to send power-delivery messages -+ * too late (5 seconds according to the specification), the -+ * power-supply reacts with a hard-reset. That removes the -+ * power from VBUS for some time, which resets te whole board. -+ */ -+ status = "fail"; -+ -+ usb_con: connector { -+ compatible = "usb-c-connector"; -+ label = "USB-C"; -+ data-role = "dual"; -+ power-role = "sink"; -+ try-power-role = "sink"; -+ op-sink-microwatt = <1000000>; -+ sink-pdos = -+ <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>, -+ <PDO_VAR(5000, 20000, 5000)>; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ port@0 { -+ reg = <0>; -+ usbc0_orien_sw: endpoint { -+ remote-endpoint = <&usbdp_phy0_orientation_switch>; -+ }; -+ }; -+ -+ port@1 { -+ reg = <1>; -+ usbc0_role_sw: endpoint { -+ remote-endpoint = <&dwc3_0_role_switch>; -+ }; -+ }; -+ -+ port@2 { -+ reg = <2>; -+ dp_altmode_mux: endpoint { -+ remote-endpoint = <&usbdp_phy0_dp_altmode_mux>; -+ }; -+ }; -+ }; -+ }; -+ }; -+}; -+ - &i2c6 { - status = "okay"; - -@@ -391,6 +463,10 @@ usb { - vcc5v0_host_en: vcc5v0-host-en { - rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; - }; -+ -+ usbc0_int: usbc0-int { -+ rockchip,pins = <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; - }; - }; - -@@ -803,6 +879,14 @@ &uart2 { - status = "okay"; - }; - -+&u2phy0 { -+ status = "okay"; -+}; -+ -+&u2phy0_otg { -+ status = "okay"; -+}; -+ - &u2phy1 { - status = "okay"; - }; -@@ -834,6 +918,29 @@ &usbdp_phy1 { - status = "okay"; - }; - -+&usbdp_phy0 { -+ mode-switch; -+ orientation-switch; -+ sbu1-dc-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>; -+ sbu2-dc-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>; -+ status = "okay"; -+ -+ port { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ usbdp_phy0_orientation_switch: endpoint@0 { -+ reg = <0>; -+ remote-endpoint = <&usbc0_orien_sw>; -+ }; -+ -+ usbdp_phy0_dp_altmode_mux: endpoint@1 { -+ reg = <1>; -+ remote-endpoint = <&dp_altmode_mux>; -+ }; -+ }; -+}; -+ - &usb_host0_ehci { - status = "okay"; - }; -@@ -842,6 +949,20 @@ &usb_host0_ohci { - status = "okay"; - }; - -+&usb_host0_xhci { -+ usb-role-switch; -+ status = "okay"; -+ -+ port { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ dwc3_0_role_switch: endpoint { -+ remote-endpoint = <&usbc0_role_sw>; -+ }; -+ }; -+}; -+ - &usb_host1_ehci { - status = "okay"; - }; --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0005-math.h-add-DIV_ROUND_UP_NO_OVERFLOW.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0005-math.h-add-DIV_ROUND_UP_NO_OVERFLOW.patch deleted file mode 100644 index 6f599e7fa3..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0005-math.h-add-DIV_ROUND_UP_NO_OVERFLOW.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 6fc00d08c9d4f0a455f4f4459e202e9cb9239354 Mon Sep 17 00:00:00 2001 -From: Sebastian Reichel <sebastian.reichel@collabora.com> -Date: Tue, 24 Oct 2023 16:09:35 +0200 -Subject: [PATCH 05/63] math.h: add DIV_ROUND_UP_NO_OVERFLOW - -Add a new DIV_ROUND_UP helper, which cannot overflow when -big numbers are being used. - -Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> ---- - include/linux/math.h | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/include/linux/math.h b/include/linux/math.h -index f5f18dc3616b..179bddeec31d 100644 ---- a/include/linux/math.h -+++ b/include/linux/math.h -@@ -36,6 +36,17 @@ - - #define DIV_ROUND_UP __KERNEL_DIV_ROUND_UP - -+/** -+ * DIV_ROUND_UP_NO_OVERFLOW - divide two numbers and always round up -+ * @n: numerator / dividend -+ * @d: denominator / divisor -+ * -+ * This functions does the same as DIV_ROUND_UP, but internally uses a -+ * division and a modulo operation instead of math tricks. This way it -+ * avoids overflowing when handling big numbers. -+ */ -+#define DIV_ROUND_UP_NO_OVERFLOW(n, d) (((n) / (d)) + !!((n) % (d))) -+ - #define DIV_ROUND_DOWN_ULL(ll, d) \ - ({ unsigned long long _tmp = (ll); do_div(_tmp, d); _tmp; }) - --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0006-clk-divider-Fix-divisor-masking-on-64-bit-platforms.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0006-clk-divider-Fix-divisor-masking-on-64-bit-platforms.patch deleted file mode 100644 index 751b680f0b..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0006-clk-divider-Fix-divisor-masking-on-64-bit-platforms.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 329168a1aad9262c40e437b3cdd9d4f5b13057e0 Mon Sep 17 00:00:00 2001 -From: Sebastian Reichel <sebastian.reichel@collabora.com> -Date: Tue, 24 Oct 2023 16:13:50 +0200 -Subject: [PATCH 06/63] clk: divider: Fix divisor masking on 64 bit platforms - -The clock framework handles clock rates as "unsigned long", so u32 on -32-bit architectures and u64 on 64-bit architectures. - -The current code casts the dividend to u64 on 32-bit to avoid a -potential overflow. For example DIV_ROUND_UP(3000000000, 1500000000) -= (3.0G + 1.5G - 1) / 1.5G = = OVERFLOW / 1.5G, which has been -introduced in commit 9556f9dad8f5 ("clk: divider: handle integer overflow -when dividing large clock rates"). - -On 64 bit platforms this masks the divisor, so that only the lower -32 bit are used. Thus requesting a frequency >= 4.3GHz results -in incorrect values. For example requesting 4300000000 (4.3 GHz) will -effectively request ca. 5 MHz. Requesting clk_round_rate(clk, ULONG_MAX) -is a bit of a special case, since that still returns correct values as -long as the parent clock is below 8.5 GHz. - -Fix this by switching to DIV_ROUND_UP_NO_OVERFLOW, which cannot -overflow. This avoids any requirements on the arguments (except -that divisor should not be 0 obviously). - -Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> ---- - drivers/clk/clk-divider.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c -index a2c2b5203b0a..94b4fb66a60f 100644 ---- a/drivers/clk/clk-divider.c -+++ b/drivers/clk/clk-divider.c -@@ -220,7 +220,7 @@ static int _div_round_up(const struct clk_div_table *table, - unsigned long parent_rate, unsigned long rate, - unsigned long flags) - { -- int div = DIV_ROUND_UP_ULL((u64)parent_rate, rate); -+ int div = DIV_ROUND_UP_NO_OVERFLOW(parent_rate, rate); - - if (flags & CLK_DIVIDER_POWER_OF_TWO) - div = __roundup_pow_of_two(div); -@@ -237,7 +237,7 @@ static int _div_round_closest(const struct clk_div_table *table, - int up, down; - unsigned long up_rate, down_rate; - -- up = DIV_ROUND_UP_ULL((u64)parent_rate, rate); -+ up = DIV_ROUND_UP_NO_OVERFLOW(parent_rate, rate); - down = parent_rate / rate; - - if (flags & CLK_DIVIDER_POWER_OF_TWO) { -@@ -473,7 +473,7 @@ int divider_get_val(unsigned long rate, unsigned long parent_rate, - { - unsigned int div, value; - -- div = DIV_ROUND_UP_ULL((u64)parent_rate, rate); -+ div = DIV_ROUND_UP_NO_OVERFLOW(parent_rate, rate); - - if (!_is_valid_div(table, div, flags)) - return -EINVAL; --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0007-clk-composite-replace-open-coded-abs_diff.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0007-clk-composite-replace-open-coded-abs_diff.patch deleted file mode 100644 index f78c778269..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0007-clk-composite-replace-open-coded-abs_diff.patch +++ /dev/null @@ -1,40 +0,0 @@ -From e779229fd3b286a7414bdce4b70b4b993b37feb9 Mon Sep 17 00:00:00 2001 -From: Sebastian Reichel <sebastian.reichel@collabora.com> -Date: Tue, 24 Oct 2023 18:09:57 +0200 -Subject: [PATCH 07/63] clk: composite: replace open-coded abs_diff() - -Replace the open coded abs_diff() with the existing helper function. - -Suggested-by: Andy Shevchenko <andriy.shevchenko@intel.com> -Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> ---- - drivers/clk/clk-composite.c | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c -index 66759fe28fad..478a4e594336 100644 ---- a/drivers/clk/clk-composite.c -+++ b/drivers/clk/clk-composite.c -@@ -6,6 +6,7 @@ - #include <linux/clk-provider.h> - #include <linux/device.h> - #include <linux/err.h> -+#include <linux/math.h> - #include <linux/slab.h> - - static u8 clk_composite_get_parent(struct clk_hw *hw) -@@ -119,10 +120,7 @@ static int clk_composite_determine_rate(struct clk_hw *hw, - if (ret) - continue; - -- if (req->rate >= tmp_req.rate) -- rate_diff = req->rate - tmp_req.rate; -- else -- rate_diff = tmp_req.rate - req->rate; -+ rate_diff = abs_diff(req->rate, tmp_req.rate); - - if (!rate_diff || !req->best_parent_hw - || best_rate_diff > rate_diff) { --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0008-clk-rockchip-support-clocks-registered-late.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0008-clk-rockchip-support-clocks-registered-late.patch deleted file mode 100644 index a680215c1c..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0008-clk-rockchip-support-clocks-registered-late.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 381c34d910b1a4f53fb0d95e96bf1b6679d4571f Mon Sep 17 00:00:00 2001 -From: Sebastian Reichel <sebastian.reichel@collabora.com> -Date: Fri, 8 Mar 2024 23:19:55 +0100 -Subject: [PATCH 08/63] clk: rockchip: support clocks registered late - -When some clocks are registered late and some clocks are registered -early we need to make sure the late registered clocks report probe defer -until the final registration has happened. - -But we do not want to keep reporting probe defer after the late -registration has happened. Also not all Rockchip SoCs have late -registered clocks and may not need to report probe defer at all. - -This restructures code a bit, so that there is a new function -rockchip_clk_init_early(), which should be used for initializing the CRU -structure on SoCs making use of late initialization in addition to the -early init. These platforms should call rockchip_clk_finalize() -once all clocks have been registered. - -Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> ---- - drivers/clk/rockchip/clk.c | 35 +++++++++++++++++++++++++++++++---- - drivers/clk/rockchip/clk.h | 3 +++ - 2 files changed, 34 insertions(+), 4 deletions(-) - -diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c -index 88629a9abc9c..45214607467e 100644 ---- a/drivers/clk/rockchip/clk.c -+++ b/drivers/clk/rockchip/clk.c -@@ -359,14 +359,17 @@ static struct clk *rockchip_clk_register_factor_branch(const char *name, - return hw->clk; - } - --struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np, -- void __iomem *base, -- unsigned long nr_clks) -+static struct rockchip_clk_provider *rockchip_clk_init_base( -+ struct device_node *np, void __iomem *base, -+ unsigned long nr_clks, bool has_late_clocks) - { - struct rockchip_clk_provider *ctx; - struct clk **clk_table; -+ struct clk *default_clk_val; - int i; - -+ default_clk_val = ERR_PTR(has_late_clocks ? -EPROBE_DEFER : -ENOENT); -+ - ctx = kzalloc(sizeof(struct rockchip_clk_provider), GFP_KERNEL); - if (!ctx) - return ERR_PTR(-ENOMEM); -@@ -376,7 +379,7 @@ struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np, - goto err_free; - - for (i = 0; i < nr_clks; ++i) -- clk_table[i] = ERR_PTR(-ENOENT); -+ clk_table[i] = default_clk_val; - - ctx->reg_base = base; - ctx->clk_data.clks = clk_table; -@@ -393,8 +396,32 @@ struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np, - kfree(ctx); - return ERR_PTR(-ENOMEM); - } -+ -+struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np, -+ void __iomem *base, -+ unsigned long nr_clks) -+{ -+ return rockchip_clk_init_base(np, base, nr_clks, false); -+} - EXPORT_SYMBOL_GPL(rockchip_clk_init); - -+struct rockchip_clk_provider *rockchip_clk_init_early(struct device_node *np, -+ void __iomem *base, -+ unsigned long nr_clks) -+{ -+ return rockchip_clk_init_base(np, base, nr_clks, true); -+} -+EXPORT_SYMBOL_GPL(rockchip_clk_init_early); -+ -+void rockchip_clk_finalize(struct rockchip_clk_provider *ctx) -+{ -+ int i; -+ -+ for (i = 0; i < ctx->clk_data.clk_num; ++i) -+ if (ctx->clk_data.clks[i] == ERR_PTR(-EPROBE_DEFER)) -+ ctx->clk_data.clks[i] = ERR_PTR(-ENOENT); -+} -+ - void rockchip_clk_of_add_provider(struct device_node *np, - struct rockchip_clk_provider *ctx) - { -diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h -index f1957e1c1178..4c6e2c931f8e 100644 ---- a/drivers/clk/rockchip/clk.h -+++ b/drivers/clk/rockchip/clk.h -@@ -1024,6 +1024,9 @@ struct rockchip_clk_branch { - - struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np, - void __iomem *base, unsigned long nr_clks); -+struct rockchip_clk_provider *rockchip_clk_init_early(struct device_node *np, -+ void __iomem *base, unsigned long nr_clks); -+void rockchip_clk_finalize(struct rockchip_clk_provider *ctx); - void rockchip_clk_of_add_provider(struct device_node *np, - struct rockchip_clk_provider *ctx); - unsigned long rockchip_clk_find_max_clk_id(struct rockchip_clk_branch *list, --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0009-clk-rockchip-rk3588-register-GATE_LINK-later.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0009-clk-rockchip-rk3588-register-GATE_LINK-later.patch deleted file mode 100644 index 8ec957463d..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0009-clk-rockchip-rk3588-register-GATE_LINK-later.patch +++ /dev/null @@ -1,153 +0,0 @@ -From 6271b89082a36ea91dbeda5947cae08ec95a8fbd Mon Sep 17 00:00:00 2001 -From: Sebastian Reichel <sebastian.reichel@collabora.com> -Date: Tue, 12 Mar 2024 16:12:18 +0100 -Subject: [PATCH 09/63] clk: rockchip: rk3588: register GATE_LINK later - -The proper GATE_LINK implementation will use runtime PM to handle the -linked gate clocks, which requires device context. Currently all clocks -are registered early via CLK_OF_DECLARE, which is before the kernel -knows about devices. - -Moving the full clocks registration to the probe routine does not work, -since the clocks needed for timers must be registered early. - -To work around this issue, most of the clock tree is registered early, -but GATE_LINK clocks are handled in the probe routine. Since the resets -are not needed early either, they have also been moved to the probe -routine. - -Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> ---- - drivers/clk/rockchip/clk-rk3588.c | 66 +++++++++++++++++++++++++++---- - 1 file changed, 58 insertions(+), 8 deletions(-) - -diff --git a/drivers/clk/rockchip/clk-rk3588.c b/drivers/clk/rockchip/clk-rk3588.c -index 0ffaf639f807..618bda0be5a4 100644 ---- a/drivers/clk/rockchip/clk-rk3588.c -+++ b/drivers/clk/rockchip/clk-rk3588.c -@@ -266,6 +266,8 @@ static struct rockchip_pll_rate_table rk3588_pll_rates[] = { - }, \ - } - -+static struct rockchip_clk_provider *early_ctx; -+ - static struct rockchip_cpuclk_rate_table rk3588_cpub0clk_rates[] __initdata = { - RK3588_CPUB01CLK_RATE(2496000000, 1), - RK3588_CPUB01CLK_RATE(2400000000, 1), -@@ -694,7 +696,7 @@ static struct rockchip_pll_clock rk3588_pll_clks[] __initdata = { - RK3588_MODE_CON0, 10, 15, 0, rk3588_pll_rates), - }; - --static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = { -+static struct rockchip_clk_branch rk3588_early_clk_branches[] __initdata = { - /* - * CRU Clock-Architecture - */ -@@ -2428,7 +2430,9 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = { - RK3588_CLKGATE_CON(68), 5, GFLAGS), - GATE(ACLK_AV1, "aclk_av1", "aclk_av1_pre", 0, - RK3588_CLKGATE_CON(68), 2, GFLAGS), -+}; - -+static struct rockchip_clk_branch rk3588_clk_branches[] = { - GATE_LINK(ACLK_ISP1_PRE, "aclk_isp1_pre", "aclk_isp1_root", ACLK_VI_ROOT, 0, RK3588_CLKGATE_CON(26), 6, GFLAGS), - GATE_LINK(HCLK_ISP1_PRE, "hclk_isp1_pre", "hclk_isp1_root", HCLK_VI_ROOT, 0, RK3588_CLKGATE_CON(26), 8, GFLAGS), - GATE_LINK(HCLK_NVM, "hclk_nvm", "hclk_nvm_root", ACLK_NVM_ROOT, RK3588_LINKED_CLK, RK3588_CLKGATE_CON(31), 2, GFLAGS), -@@ -2453,26 +2457,31 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = { - GATE_LINK(PCLK_VO1GRF, "pclk_vo1grf", "pclk_vo1_root", HCLK_VO1, CLK_IGNORE_UNUSED, RK3588_CLKGATE_CON(59), 12, GFLAGS), - }; - --static void __init rk3588_clk_init(struct device_node *np) -+static void __init rk3588_clk_early_init(struct device_node *np) - { - struct rockchip_clk_provider *ctx; -- unsigned long clk_nr_clks; -+ unsigned long clk_nr_clks, max_clk_id1, max_clk_id2; - void __iomem *reg_base; - -- clk_nr_clks = rockchip_clk_find_max_clk_id(rk3588_clk_branches, -- ARRAY_SIZE(rk3588_clk_branches)) + 1; -+ max_clk_id1 = rockchip_clk_find_max_clk_id(rk3588_clk_branches, -+ ARRAY_SIZE(rk3588_clk_branches)); -+ max_clk_id2 = rockchip_clk_find_max_clk_id(rk3588_early_clk_branches, -+ ARRAY_SIZE(rk3588_early_clk_branches)); -+ clk_nr_clks = max(max_clk_id1, max_clk_id2) + 1; -+ - reg_base = of_iomap(np, 0); - if (!reg_base) { - pr_err("%s: could not map cru region\n", __func__); - return; - } - -- ctx = rockchip_clk_init(np, reg_base, clk_nr_clks); -+ ctx = rockchip_clk_init_early(np, reg_base, clk_nr_clks); - if (IS_ERR(ctx)) { - pr_err("%s: rockchip clk init failed\n", __func__); - iounmap(reg_base); - return; - } -+ early_ctx = ctx; - - rockchip_clk_register_plls(ctx, rk3588_pll_clks, - ARRAY_SIZE(rk3588_pll_clks), -@@ -2491,14 +2500,55 @@ static void __init rk3588_clk_init(struct device_node *np) - &rk3588_cpub1clk_data, rk3588_cpub1clk_rates, - ARRAY_SIZE(rk3588_cpub1clk_rates)); - -+ rockchip_clk_register_branches(ctx, rk3588_early_clk_branches, -+ ARRAY_SIZE(rk3588_early_clk_branches)); -+ -+ rockchip_clk_of_add_provider(np, ctx); -+} -+CLK_OF_DECLARE_DRIVER(rk3588_cru, "rockchip,rk3588-cru", rk3588_clk_early_init); -+ -+static int clk_rk3588_probe(struct platform_device *pdev) -+{ -+ struct rockchip_clk_provider *ctx = early_ctx; -+ struct device *dev = &pdev->dev; -+ struct device_node *np = dev->of_node; -+ - rockchip_clk_register_branches(ctx, rk3588_clk_branches, - ARRAY_SIZE(rk3588_clk_branches)); - -- rk3588_rst_init(np, reg_base); -+ rockchip_clk_finalize(ctx); - -+ rk3588_rst_init(np, ctx->reg_base); - rockchip_register_restart_notifier(ctx, RK3588_GLB_SRST_FST, NULL); - -+ /* -+ * Re-add clock provider, so that the newly added clocks are also -+ * re-parented and get their defaults configured. -+ */ -+ of_clk_del_provider(np); - rockchip_clk_of_add_provider(np, ctx); -+ -+ return 0; - } - --CLK_OF_DECLARE(rk3588_cru, "rockchip,rk3588-cru", rk3588_clk_init); -+static const struct of_device_id clk_rk3588_match_table[] = { -+ { -+ .compatible = "rockchip,rk3588-cru", -+ }, -+ { } -+}; -+ -+static struct platform_driver clk_rk3588_driver = { -+ .probe = clk_rk3588_probe, -+ .driver = { -+ .name = "clk-rk3588", -+ .of_match_table = clk_rk3588_match_table, -+ .suppress_bind_attrs = true, -+ }, -+}; -+ -+static int __init rockchip_clk_rk3588_drv_register(void) -+{ -+ return platform_driver_register(&clk_rk3588_driver); -+} -+core_initcall(rockchip_clk_rk3588_drv_register); --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0010-clk-rockchip-expose-rockchip_clk_set_lookup.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0010-clk-rockchip-expose-rockchip_clk_set_lookup.patch deleted file mode 100644 index 22ff3ab9c0..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0010-clk-rockchip-expose-rockchip_clk_set_lookup.patch +++ /dev/null @@ -1,95 +0,0 @@ -From b49117a646a3d4cb6b16c34b7e541dc27b4888b5 Mon Sep 17 00:00:00 2001 -From: Sebastian Reichel <sebastian.reichel@collabora.com> -Date: Mon, 25 Mar 2024 19:29:22 +0100 -Subject: [PATCH 10/63] clk: rockchip: expose rockchip_clk_set_lookup - -Move rockchip_clk_add_lookup to clk.h, so that it can be used -by sub-devices with their own driver. These might also have to -do a lookup, so rename the function to rockchip_clk_set_lookup -and add a matching rockchip_clk_get_lookup. - -Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> ---- - drivers/clk/rockchip/clk.c | 14 ++++---------- - drivers/clk/rockchip/clk.h | 12 ++++++++++++ - 2 files changed, 16 insertions(+), 10 deletions(-) - -diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c -index 45214607467e..90eb651f1425 100644 ---- a/drivers/clk/rockchip/clk.c -+++ b/drivers/clk/rockchip/clk.c -@@ -197,12 +197,6 @@ static void rockchip_fractional_approximation(struct clk_hw *hw, - clk_fractional_divider_general_approximation(hw, rate, parent_rate, m, n); - } - --static void rockchip_clk_add_lookup(struct rockchip_clk_provider *ctx, -- struct clk *clk, unsigned int id) --{ -- ctx->clk_data.clks[id] = clk; --} -- - static struct clk *rockchip_clk_register_frac_branch( - struct rockchip_clk_provider *ctx, const char *name, - const char *const *parent_names, u8 num_parents, -@@ -292,7 +286,7 @@ static struct clk *rockchip_clk_register_frac_branch( - return mux_clk; - } - -- rockchip_clk_add_lookup(ctx, mux_clk, child->id); -+ rockchip_clk_set_lookup(ctx, mux_clk, child->id); - - /* notifier on the fraction divider to catch rate changes */ - if (frac->mux_frac_idx >= 0) { -@@ -451,7 +445,7 @@ void rockchip_clk_register_plls(struct rockchip_clk_provider *ctx, - continue; - } - -- rockchip_clk_add_lookup(ctx, clk, list->id); -+ rockchip_clk_set_lookup(ctx, clk, list->id); - } - } - EXPORT_SYMBOL_GPL(rockchip_clk_register_plls); -@@ -613,7 +607,7 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx, - continue; - } - -- rockchip_clk_add_lookup(ctx, clk, list->id); -+ rockchip_clk_set_lookup(ctx, clk, list->id); - } - } - EXPORT_SYMBOL_GPL(rockchip_clk_register_branches); -@@ -637,7 +631,7 @@ void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx, - return; - } - -- rockchip_clk_add_lookup(ctx, clk, lookup_id); -+ rockchip_clk_set_lookup(ctx, clk, lookup_id); - } - EXPORT_SYMBOL_GPL(rockchip_clk_register_armclk); - -diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h -index 4c6e2c931f8e..d9e071ca9c5d 100644 ---- a/drivers/clk/rockchip/clk.h -+++ b/drivers/clk/rockchip/clk.h -@@ -1022,6 +1022,18 @@ struct rockchip_clk_branch { - #define SGRF_GATE(_id, cname, pname) \ - FACTOR(_id, cname, pname, 0, 1, 1) - -+static inline struct clk *rockchip_clk_get_lookup(struct rockchip_clk_provider *ctx, -+ unsigned int id) -+{ -+ return ctx->clk_data.clks[id]; -+} -+ -+static inline void rockchip_clk_set_lookup(struct rockchip_clk_provider *ctx, -+ struct clk *clk, unsigned int id) -+{ -+ ctx->clk_data.clks[id] = clk; -+} -+ - struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np, - void __iomem *base, unsigned long nr_clks); - struct rockchip_clk_provider *rockchip_clk_init_early(struct device_node *np, --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0011-clk-rockchip-implement-linked-gate-clock-support.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0011-clk-rockchip-implement-linked-gate-clock-support.patch deleted file mode 100644 index 9c9e9b9779..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0011-clk-rockchip-implement-linked-gate-clock-support.patch +++ /dev/null @@ -1,326 +0,0 @@ -From cad5b8c9b62eda0625f6fe8200fe88960971f4a9 Mon Sep 17 00:00:00 2001 -From: Sebastian Reichel <sebastian.reichel@collabora.com> -Date: Mon, 25 Mar 2024 19:42:07 +0100 -Subject: [PATCH 11/63] clk: rockchip: implement linked gate clock support - -Recent Rockchip SoCs have a new hardware block called Native Interface -Unit (NIU), which gates clocks to devices behind them. These clock -gates will only have a running output clock when all of the following -conditions are met: - -1. the parent clock is enabled -2. the enable bit is set correctly -3. the linked clock is enabled - -To handle them this code registers them as a normal gate type clock, -which takes care of condition 1 + 2. The linked clock is handled by -using runtime PM clocks. Handling it via runtime PM requires setting -up a struct device for each of these clocks with a driver attached -to use the correct runtime PM operations. Thus the complete handling -of these clocks has been moved into its own driver. - -Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> ---- - drivers/clk/rockchip/Makefile | 1 + - drivers/clk/rockchip/clk-rk3588.c | 23 +-------- - drivers/clk/rockchip/clk.c | 52 +++++++++++++++++++ - drivers/clk/rockchip/clk.h | 25 +++++++++ - drivers/clk/rockchip/gate-link.c | 85 +++++++++++++++++++++++++++++++ - 5 files changed, 165 insertions(+), 21 deletions(-) - create mode 100644 drivers/clk/rockchip/gate-link.c - -diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile -index af2ade54a7ef..3fe7616f0ebe 100644 ---- a/drivers/clk/rockchip/Makefile -+++ b/drivers/clk/rockchip/Makefile -@@ -13,6 +13,7 @@ clk-rockchip-y += clk-inverter.o - clk-rockchip-y += clk-mmc-phase.o - clk-rockchip-y += clk-muxgrf.o - clk-rockchip-y += clk-ddr.o -+clk-rockchip-y += gate-link.o - clk-rockchip-$(CONFIG_RESET_CONTROLLER) += softrst.o - - obj-$(CONFIG_CLK_PX30) += clk-px30.o -diff --git a/drivers/clk/rockchip/clk-rk3588.c b/drivers/clk/rockchip/clk-rk3588.c -index 618bda0be5a4..d76ab27dd1b8 100644 ---- a/drivers/clk/rockchip/clk-rk3588.c -+++ b/drivers/clk/rockchip/clk-rk3588.c -@@ -12,25 +12,6 @@ - #include <dt-bindings/clock/rockchip,rk3588-cru.h> - #include "clk.h" - --/* -- * Recent Rockchip SoCs have a new hardware block called Native Interface -- * Unit (NIU), which gates clocks to devices behind them. These effectively -- * need two parent clocks. -- * -- * Downstream enables the linked clock via runtime PM whenever the gate is -- * enabled. This implementation uses separate clock nodes for each of the -- * linked gate clocks, which leaks parts of the clock tree into DT. -- * -- * The GATE_LINK macro instead takes the second parent via 'linkname', but -- * ignores the information. Once the clock framework is ready to handle it, the -- * information should be passed on here. But since these clocks are required to -- * access multiple relevant IP blocks, such as PCIe or USB, we mark all linked -- * clocks critical until a better solution is available. This will waste some -- * power, but avoids leaking implementation details into DT or hanging the -- * system. -- */ --#define GATE_LINK(_id, cname, pname, linkedclk, f, o, b, gf) \ -- GATE(_id, cname, pname, f, o, b, gf) - #define RK3588_LINKED_CLK CLK_IS_CRITICAL - - -@@ -2513,8 +2494,8 @@ static int clk_rk3588_probe(struct platform_device *pdev) - struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node; - -- rockchip_clk_register_branches(ctx, rk3588_clk_branches, -- ARRAY_SIZE(rk3588_clk_branches)); -+ rockchip_clk_register_late_branches(dev, ctx, rk3588_clk_branches, -+ ARRAY_SIZE(rk3588_clk_branches)); - - rockchip_clk_finalize(ctx); - -diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c -index 90eb651f1425..2ea4d616840d 100644 ---- a/drivers/clk/rockchip/clk.c -+++ b/drivers/clk/rockchip/clk.c -@@ -19,6 +19,7 @@ - #include <linux/clk-provider.h> - #include <linux/io.h> - #include <linux/mfd/syscon.h> -+#include <linux/platform_device.h> - #include <linux/regmap.h> - #include <linux/reboot.h> - -@@ -467,6 +468,29 @@ unsigned long rockchip_clk_find_max_clk_id(struct rockchip_clk_branch *list, - } - EXPORT_SYMBOL_GPL(rockchip_clk_find_max_clk_id); - -+static struct platform_device *rockchip_clk_register_gate_link( -+ struct device *parent_dev, -+ struct rockchip_clk_provider *ctx, -+ struct rockchip_clk_branch *clkbr) -+{ -+ struct rockchip_gate_link_platdata gate_link_pdata = { -+ .ctx = ctx, -+ .clkbr = clkbr, -+ }; -+ -+ struct platform_device_info pdevinfo = { -+ .parent = parent_dev, -+ .name = "rockchip-gate-link-clk", -+ .id = clkbr->id, -+ .fwnode = dev_fwnode(parent_dev), -+ .of_node_reused = true, -+ .data = &gate_link_pdata, -+ .size_data = sizeof(gate_link_pdata), -+ }; -+ -+ return platform_device_register_full(&pdevinfo); -+} -+ - void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx, - struct rockchip_clk_branch *list, - unsigned int nr_clk) -@@ -592,6 +616,9 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx, - list->div_width, list->div_flags, - ctx->reg_base, &ctx->lock); - break; -+ case branch_linked_gate: -+ /* must be registered late, fall-through for error message */ -+ break; - } - - /* none of the cases above matched */ -@@ -612,6 +639,31 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx, - } - EXPORT_SYMBOL_GPL(rockchip_clk_register_branches); - -+void rockchip_clk_register_late_branches(struct device *dev, -+ struct rockchip_clk_provider *ctx, -+ struct rockchip_clk_branch *list, -+ unsigned int nr_clk) -+{ -+ unsigned int idx; -+ -+ for (idx = 0; idx < nr_clk; idx++, list++) { -+ struct platform_device *pdev = NULL; -+ -+ switch (list->branch_type) { -+ case branch_linked_gate: -+ pdev = rockchip_clk_register_gate_link(dev, ctx, list); -+ break; -+ default: -+ dev_err(dev, "unknown clock type %d\n", list->branch_type); -+ break; -+ } -+ -+ if (!pdev) -+ dev_err(dev, "failed to register device for clock %s\n", list->name); -+ } -+} -+EXPORT_SYMBOL_GPL(rockchip_clk_register_late_branches); -+ - void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx, - unsigned int lookup_id, - const char *name, const char *const *parent_names, -diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h -index d9e071ca9c5d..9b37d44b9e5d 100644 ---- a/drivers/clk/rockchip/clk.h -+++ b/drivers/clk/rockchip/clk.h -@@ -570,6 +570,7 @@ enum rockchip_clk_branch_type { - branch_divider, - branch_fraction_divider, - branch_gate, -+ branch_linked_gate, - branch_mmc, - branch_inverter, - branch_factor, -@@ -597,6 +598,7 @@ struct rockchip_clk_branch { - int gate_offset; - u8 gate_shift; - u8 gate_flags; -+ unsigned int linked_clk_id; - struct rockchip_clk_branch *child; - }; - -@@ -895,6 +897,20 @@ struct rockchip_clk_branch { - .gate_flags = gf, \ - } - -+#define GATE_LINK(_id, cname, pname, linkedclk, f, o, b, gf) \ -+ { \ -+ .id = _id, \ -+ .branch_type = branch_linked_gate, \ -+ .name = cname, \ -+ .parent_names = (const char *[]){ pname }, \ -+ .linked_clk_id = linkedclk, \ -+ .num_parents = 1, \ -+ .flags = f, \ -+ .gate_offset = o, \ -+ .gate_shift = b, \ -+ .gate_flags = gf, \ -+ } -+ - #define MMC(_id, cname, pname, offset, shift) \ - { \ - .id = _id, \ -@@ -1034,6 +1050,11 @@ static inline void rockchip_clk_set_lookup(struct rockchip_clk_provider *ctx, - ctx->clk_data.clks[id] = clk; - } - -+struct rockchip_gate_link_platdata { -+ struct rockchip_clk_provider *ctx; -+ struct rockchip_clk_branch *clkbr; -+}; -+ - struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np, - void __iomem *base, unsigned long nr_clks); - struct rockchip_clk_provider *rockchip_clk_init_early(struct device_node *np, -@@ -1046,6 +1067,10 @@ unsigned long rockchip_clk_find_max_clk_id(struct rockchip_clk_branch *list, - void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx, - struct rockchip_clk_branch *list, - unsigned int nr_clk); -+void rockchip_clk_register_late_branches(struct device *dev, -+ struct rockchip_clk_provider *ctx, -+ struct rockchip_clk_branch *list, -+ unsigned int nr_clk); - void rockchip_clk_register_plls(struct rockchip_clk_provider *ctx, - struct rockchip_pll_clock *pll_list, - unsigned int nr_pll, int grf_lock_offset); -diff --git a/drivers/clk/rockchip/gate-link.c b/drivers/clk/rockchip/gate-link.c -new file mode 100644 -index 000000000000..cd0f7a2d30ab ---- /dev/null -+++ b/drivers/clk/rockchip/gate-link.c -@@ -0,0 +1,85 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ * Copyright (c) 2024 Collabora Ltd. -+ * Author: Sebastian Reichel <sebastian.reichel@collabora.com> -+ */ -+ -+#include <linux/clk.h> -+#include <linux/platform_device.h> -+#include <linux/pm_clock.h> -+#include <linux/pm_runtime.h> -+#include <linux/property.h> -+#include "clk.h" -+ -+static int rk_clk_gate_link_register(struct device *dev, -+ struct rockchip_clk_provider *ctx, -+ struct rockchip_clk_branch *clkbr) -+{ -+ unsigned long flags = clkbr->flags | CLK_SET_RATE_PARENT; -+ struct clk *clk; -+ -+ clk = clk_register_gate(dev, clkbr->name, clkbr->parent_names[0], -+ flags, ctx->reg_base + clkbr->gate_offset, -+ clkbr->gate_shift, clkbr->gate_flags, -+ &ctx->lock); -+ -+ if (IS_ERR(clk)) -+ return PTR_ERR(clk); -+ -+ rockchip_clk_set_lookup(ctx, clk, clkbr->id); -+ return 0; -+} -+ -+static int rk_clk_gate_link_probe(struct platform_device *pdev) -+{ -+ struct rockchip_gate_link_platdata *pdata; -+ struct device *dev = &pdev->dev; -+ struct clk *linked_clk; -+ int ret; -+ -+ pdata = dev_get_platdata(dev); -+ if (!pdata) -+ return dev_err_probe(dev, -ENODEV, "missing platform data"); -+ -+ ret = devm_pm_runtime_enable(dev); -+ if (ret) -+ return ret; -+ -+ ret = devm_pm_clk_create(dev); -+ if (ret) -+ return ret; -+ -+ linked_clk = rockchip_clk_get_lookup(pdata->ctx, pdata->clkbr->linked_clk_id); -+ ret = pm_clk_add_clk(dev, linked_clk); -+ if (ret) -+ return ret; -+ -+ ret = rk_clk_gate_link_register(dev, pdata->ctx, pdata->clkbr); -+ if (ret) -+ goto err; -+ -+ return 0; -+ -+err: -+ pm_clk_remove_clk(dev, linked_clk); -+ return ret; -+} -+ -+static const struct dev_pm_ops rk_clk_gate_link_pm_ops = { -+ SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL) -+}; -+ -+static struct platform_driver rk_clk_gate_link_driver = { -+ .probe = rk_clk_gate_link_probe, -+ .driver = { -+ .name = "rockchip-gate-link-clk", -+ .pm = &rk_clk_gate_link_pm_ops, -+ .suppress_bind_attrs = true, -+ }, -+}; -+ -+static int __init rk_clk_gate_link_drv_register(void) -+{ -+ return platform_driver_register(&rk_clk_gate_link_driver); -+} -+core_initcall(rk_clk_gate_link_drv_register); --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0012-clk-rockchip-rk3588-drop-RK3588_LINKED_CLK.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0012-clk-rockchip-rk3588-drop-RK3588_LINKED_CLK.patch deleted file mode 100644 index 6fcf81dc53..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0012-clk-rockchip-rk3588-drop-RK3588_LINKED_CLK.patch +++ /dev/null @@ -1,115 +0,0 @@ -From ef7f6a0eee989648b6983278ddb463f43b9869ac Mon Sep 17 00:00:00 2001 -From: Sebastian Reichel <sebastian.reichel@collabora.com> -Date: Fri, 8 Mar 2024 23:32:05 +0100 -Subject: [PATCH 12/63] clk: rockchip: rk3588: drop RK3588_LINKED_CLK - -With the proper GATE_LINK support, we no longer need to keep the -linked clocks always on. Thus it's time to drop the CLK_IS_CRITICAL -flag for them. - -Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> ---- - drivers/clk/rockchip/clk-rk3588.c | 27 ++++++++++++--------------- - 1 file changed, 12 insertions(+), 15 deletions(-) - -diff --git a/drivers/clk/rockchip/clk-rk3588.c b/drivers/clk/rockchip/clk-rk3588.c -index d76ab27dd1b8..46dcbbcee54e 100644 ---- a/drivers/clk/rockchip/clk-rk3588.c -+++ b/drivers/clk/rockchip/clk-rk3588.c -@@ -12,9 +12,6 @@ - #include <dt-bindings/clock/rockchip,rk3588-cru.h> - #include "clk.h" - --#define RK3588_LINKED_CLK CLK_IS_CRITICAL -- -- - #define RK3588_GRF_SOC_STATUS0 0x600 - #define RK3588_PHYREF_ALT_GATE 0xc38 - -@@ -1439,7 +1436,7 @@ static struct rockchip_clk_branch rk3588_early_clk_branches[] __initdata = { - COMPOSITE_NODIV(HCLK_NVM_ROOT, "hclk_nvm_root", mux_200m_100m_50m_24m_p, 0, - RK3588_CLKSEL_CON(77), 0, 2, MFLAGS, - RK3588_CLKGATE_CON(31), 0, GFLAGS), -- COMPOSITE(ACLK_NVM_ROOT, "aclk_nvm_root", gpll_cpll_p, RK3588_LINKED_CLK, -+ COMPOSITE(ACLK_NVM_ROOT, "aclk_nvm_root", gpll_cpll_p, 0, - RK3588_CLKSEL_CON(77), 7, 1, MFLAGS, 2, 5, DFLAGS, - RK3588_CLKGATE_CON(31), 1, GFLAGS), - GATE(ACLK_EMMC, "aclk_emmc", "aclk_nvm_root", 0, -@@ -1668,13 +1665,13 @@ static struct rockchip_clk_branch rk3588_early_clk_branches[] __initdata = { - RK3588_CLKGATE_CON(42), 9, GFLAGS), - - /* vdpu */ -- COMPOSITE(ACLK_VDPU_ROOT, "aclk_vdpu_root", gpll_cpll_aupll_p, RK3588_LINKED_CLK, -+ COMPOSITE(ACLK_VDPU_ROOT, "aclk_vdpu_root", gpll_cpll_aupll_p, 0, - RK3588_CLKSEL_CON(98), 5, 2, MFLAGS, 0, 5, DFLAGS, - RK3588_CLKGATE_CON(44), 0, GFLAGS), - COMPOSITE_NODIV(ACLK_VDPU_LOW_ROOT, "aclk_vdpu_low_root", mux_400m_200m_100m_24m_p, 0, - RK3588_CLKSEL_CON(98), 7, 2, MFLAGS, - RK3588_CLKGATE_CON(44), 1, GFLAGS), -- COMPOSITE_NODIV(HCLK_VDPU_ROOT, "hclk_vdpu_root", mux_200m_100m_50m_24m_p, RK3588_LINKED_CLK, -+ COMPOSITE_NODIV(HCLK_VDPU_ROOT, "hclk_vdpu_root", mux_200m_100m_50m_24m_p, 0, - RK3588_CLKSEL_CON(98), 9, 2, MFLAGS, - RK3588_CLKGATE_CON(44), 2, GFLAGS), - COMPOSITE(ACLK_JPEG_DECODER_ROOT, "aclk_jpeg_decoder_root", gpll_cpll_aupll_spll_p, 0, -@@ -1725,9 +1722,9 @@ static struct rockchip_clk_branch rk3588_early_clk_branches[] __initdata = { - COMPOSITE(ACLK_RKVENC0_ROOT, "aclk_rkvenc0_root", gpll_cpll_npll_p, 0, - RK3588_CLKSEL_CON(102), 7, 2, MFLAGS, 2, 5, DFLAGS, - RK3588_CLKGATE_CON(47), 1, GFLAGS), -- GATE(HCLK_RKVENC0, "hclk_rkvenc0", "hclk_rkvenc0_root", RK3588_LINKED_CLK, -+ GATE(HCLK_RKVENC0, "hclk_rkvenc0", "hclk_rkvenc0_root", 0, - RK3588_CLKGATE_CON(47), 4, GFLAGS), -- GATE(ACLK_RKVENC0, "aclk_rkvenc0", "aclk_rkvenc0_root", RK3588_LINKED_CLK, -+ GATE(ACLK_RKVENC0, "aclk_rkvenc0", "aclk_rkvenc0_root", 0, - RK3588_CLKGATE_CON(47), 5, GFLAGS), - COMPOSITE(CLK_RKVENC0_CORE, "clk_rkvenc0_core", gpll_cpll_aupll_npll_p, 0, - RK3588_CLKSEL_CON(102), 14, 2, MFLAGS, 9, 5, DFLAGS, -@@ -1737,10 +1734,10 @@ static struct rockchip_clk_branch rk3588_early_clk_branches[] __initdata = { - RK3588_CLKGATE_CON(48), 6, GFLAGS), - - /* vi */ -- COMPOSITE(ACLK_VI_ROOT, "aclk_vi_root", gpll_cpll_npll_aupll_spll_p, RK3588_LINKED_CLK, -+ COMPOSITE(ACLK_VI_ROOT, "aclk_vi_root", gpll_cpll_npll_aupll_spll_p, 0, - RK3588_CLKSEL_CON(106), 5, 3, MFLAGS, 0, 5, DFLAGS, - RK3588_CLKGATE_CON(49), 0, GFLAGS), -- COMPOSITE_NODIV(HCLK_VI_ROOT, "hclk_vi_root", mux_200m_100m_50m_24m_p, RK3588_LINKED_CLK, -+ COMPOSITE_NODIV(HCLK_VI_ROOT, "hclk_vi_root", mux_200m_100m_50m_24m_p, 0, - RK3588_CLKSEL_CON(106), 8, 2, MFLAGS, - RK3588_CLKGATE_CON(49), 1, GFLAGS), - COMPOSITE_NODIV(PCLK_VI_ROOT, "pclk_vi_root", mux_100m_50m_24m_p, 0, -@@ -1910,10 +1907,10 @@ static struct rockchip_clk_branch rk3588_early_clk_branches[] __initdata = { - COMPOSITE(ACLK_VOP_ROOT, "aclk_vop_root", gpll_cpll_dmyaupll_npll_spll_p, 0, - RK3588_CLKSEL_CON(110), 5, 3, MFLAGS, 0, 5, DFLAGS, - RK3588_CLKGATE_CON(52), 0, GFLAGS), -- COMPOSITE_NODIV(ACLK_VOP_LOW_ROOT, "aclk_vop_low_root", mux_400m_200m_100m_24m_p, RK3588_LINKED_CLK, -+ COMPOSITE_NODIV(ACLK_VOP_LOW_ROOT, "aclk_vop_low_root", mux_400m_200m_100m_24m_p, 0, - RK3588_CLKSEL_CON(110), 8, 2, MFLAGS, - RK3588_CLKGATE_CON(52), 1, GFLAGS), -- COMPOSITE_NODIV(HCLK_VOP_ROOT, "hclk_vop_root", mux_200m_100m_50m_24m_p, RK3588_LINKED_CLK, -+ COMPOSITE_NODIV(HCLK_VOP_ROOT, "hclk_vop_root", mux_200m_100m_50m_24m_p, 0, - RK3588_CLKSEL_CON(110), 10, 2, MFLAGS, - RK3588_CLKGATE_CON(52), 2, GFLAGS), - COMPOSITE_NODIV(PCLK_VOP_ROOT, "pclk_vop_root", mux_100m_50m_24m_p, 0, -@@ -2416,7 +2413,7 @@ static struct rockchip_clk_branch rk3588_early_clk_branches[] __initdata = { - static struct rockchip_clk_branch rk3588_clk_branches[] = { - GATE_LINK(ACLK_ISP1_PRE, "aclk_isp1_pre", "aclk_isp1_root", ACLK_VI_ROOT, 0, RK3588_CLKGATE_CON(26), 6, GFLAGS), - GATE_LINK(HCLK_ISP1_PRE, "hclk_isp1_pre", "hclk_isp1_root", HCLK_VI_ROOT, 0, RK3588_CLKGATE_CON(26), 8, GFLAGS), -- GATE_LINK(HCLK_NVM, "hclk_nvm", "hclk_nvm_root", ACLK_NVM_ROOT, RK3588_LINKED_CLK, RK3588_CLKGATE_CON(31), 2, GFLAGS), -+ GATE_LINK(HCLK_NVM, "hclk_nvm", "hclk_nvm_root", ACLK_NVM_ROOT, 0, RK3588_CLKGATE_CON(31), 2, GFLAGS), - GATE_LINK(ACLK_USB, "aclk_usb", "aclk_usb_root", ACLK_VO1USB_TOP_ROOT, 0, RK3588_CLKGATE_CON(42), 2, GFLAGS), - GATE_LINK(HCLK_USB, "hclk_usb", "hclk_usb_root", HCLK_VO1USB_TOP_ROOT, 0, RK3588_CLKGATE_CON(42), 3, GFLAGS), - GATE_LINK(ACLK_JPEG_DECODER_PRE, "aclk_jpeg_decoder_pre", "aclk_jpeg_decoder_root", ACLK_VDPU_ROOT, 0, RK3588_CLKGATE_CON(44), 7, GFLAGS), -@@ -2428,9 +2425,9 @@ static struct rockchip_clk_branch rk3588_clk_branches[] = { - GATE_LINK(HCLK_RKVDEC1_PRE, "hclk_rkvdec1_pre", "hclk_rkvdec1_root", HCLK_VDPU_ROOT, 0, RK3588_CLKGATE_CON(41), 4, GFLAGS), - GATE_LINK(ACLK_RKVDEC1_PRE, "aclk_rkvdec1_pre", "aclk_rkvdec1_root", ACLK_VDPU_ROOT, 0, RK3588_CLKGATE_CON(41), 5, GFLAGS), - GATE_LINK(ACLK_HDCP0_PRE, "aclk_hdcp0_pre", "aclk_vo0_root", ACLK_VOP_LOW_ROOT, 0, RK3588_CLKGATE_CON(55), 9, GFLAGS), -- GATE_LINK(HCLK_VO0, "hclk_vo0", "hclk_vo0_root", HCLK_VOP_ROOT, RK3588_LINKED_CLK, RK3588_CLKGATE_CON(55), 5, GFLAGS), -+ GATE_LINK(HCLK_VO0, "hclk_vo0", "hclk_vo0_root", HCLK_VOP_ROOT, 0, RK3588_CLKGATE_CON(55), 5, GFLAGS), - GATE_LINK(ACLK_HDCP1_PRE, "aclk_hdcp1_pre", "aclk_hdcp1_root", ACLK_VO1USB_TOP_ROOT, 0, RK3588_CLKGATE_CON(59), 6, GFLAGS), -- GATE_LINK(HCLK_VO1, "hclk_vo1", "hclk_vo1_root", HCLK_VO1USB_TOP_ROOT, RK3588_LINKED_CLK, RK3588_CLKGATE_CON(59), 9, GFLAGS), -+ GATE_LINK(HCLK_VO1, "hclk_vo1", "hclk_vo1_root", HCLK_VO1USB_TOP_ROOT, 0, RK3588_CLKGATE_CON(59), 9, GFLAGS), - GATE_LINK(ACLK_AV1_PRE, "aclk_av1_pre", "aclk_av1_root", ACLK_VDPU_ROOT, 0, RK3588_CLKGATE_CON(68), 1, GFLAGS), - GATE_LINK(PCLK_AV1_PRE, "pclk_av1_pre", "pclk_av1_root", HCLK_VDPU_ROOT, 0, RK3588_CLKGATE_CON(68), 4, GFLAGS), - GATE_LINK(HCLK_SDIO_PRE, "hclk_sdio_pre", "hclk_sdio_root", HCLK_NVM, 0, RK3588_CLKGATE_CON(75), 1, GFLAGS), --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0013-arm64-dts-rockchip-rk3588-evb1-add-bluetooth-rfkill.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0013-arm64-dts-rockchip-rk3588-evb1-add-bluetooth-rfkill.patch deleted file mode 100644 index 592c1593db..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0013-arm64-dts-rockchip-rk3588-evb1-add-bluetooth-rfkill.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 67992ad1e5f60075253698030e552034ab8a3c5e Mon Sep 17 00:00:00 2001 -From: Sebastian Reichel <sebastian.reichel@collabora.com> -Date: Tue, 2 Jan 2024 09:35:43 +0100 -Subject: [PATCH 13/63] arm64: dts: rockchip: rk3588-evb1: add bluetooth rfkill - -Add rfkill support for bluetooth. Bluetooth support itself is still -missing, but this ensures bluetooth can be powered off properly. - -Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> ---- - arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts | 15 +++++++++++++++ - 1 file changed, 15 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts -index 00f660d50127..6cedcb8eabc9 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts -@@ -120,6 +120,15 @@ backlight: backlight { - pwms = <&pwm2 0 25000 0>; - }; - -+ bluetooth-rfkill { -+ compatible = "rfkill-gpio"; -+ label = "rfkill-bluetooth"; -+ radio-type = "bluetooth"; -+ shutdown-gpios = <&gpio3 RK_PA6 GPIO_ACTIVE_LOW>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&bluetooth_pwren>; -+ }; -+ - pcie20_avdd0v85: pcie20-avdd0v85-regulator { - compatible = "regulator-fixed"; - regulator-name = "pcie20_avdd0v85"; -@@ -442,6 +451,12 @@ speaker_amplifier_en: speaker-amplifier-en { - }; - }; - -+ bluetooth { -+ bluetooth_pwren: bluetooth-pwren { -+ rockchip,pins = <3 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+ - rtl8111 { - rtl8111_isolate: rtl8111-isolate { - rockchip,pins = <1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>; --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0014-arm64-dts-rockchip-rk3588-evb1-improve-PCIe-ethernet.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0014-arm64-dts-rockchip-rk3588-evb1-improve-PCIe-ethernet.patch deleted file mode 100644 index 413d600638..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0014-arm64-dts-rockchip-rk3588-evb1-improve-PCIe-ethernet.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 6b7aae0bf361c8f1d4013acf2b848a628489d926 Mon Sep 17 00:00:00 2001 -From: Sebastian Reichel <sebastian.reichel@collabora.com> -Date: Tue, 2 Jan 2024 09:39:11 +0100 -Subject: [PATCH 14/63] arm64: dts: rockchip: rk3588-evb1: improve PCIe - ethernet pin muxing - -Also describe clkreq and wake signals in the PCIe pinmux used -by the onboard LAN card. - -Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> ---- - arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts -index 6cedcb8eabc9..6f6af801e7f3 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts -@@ -420,7 +420,7 @@ rgmii_phy: ethernet-phy@1 { - &pcie2x1l1 { - reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; -- pinctrl-0 = <&pcie2_1_rst>, <&rtl8111_isolate>; -+ pinctrl-0 = <&pcie2_1_rst>, <&pcie2_1_wake>, <&pcie2_1_clkreq>, <&rtl8111_isolate>; - status = "okay"; - }; - -@@ -480,6 +480,14 @@ pcie2 { - pcie2_1_rst: pcie2-1-rst { - rockchip,pins = <4 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; - }; -+ -+ pcie2_1_wake: pcie2-1-wake { -+ rockchip,pins = <4 RK_PA1 4 &pcfg_pull_none>; -+ }; -+ -+ pcie2_1_clkreq: pcie2-1-clkreq { -+ rockchip,pins = <4 RK_PA0 4 &pcfg_pull_none>; -+ }; - }; - - pcie3 { --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0015-arm64-dts-rockchip-Slow-down-EMMC-a-bit-to-keep-IO-s.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0015-arm64-dts-rockchip-Slow-down-EMMC-a-bit-to-keep-IO-s.patch deleted file mode 100644 index 2e962e0004..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0015-arm64-dts-rockchip-Slow-down-EMMC-a-bit-to-keep-IO-s.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 4d2856769b00e826992dbf7c8d69e11b8a6b7b8b Mon Sep 17 00:00:00 2001 -From: "Carsten Haitzler (Rasterman)" <raster@rasterman.com> -Date: Tue, 6 Feb 2024 10:12:54 +0000 -Subject: [PATCH 15/63] arm64: dts: rockchip: Slow down EMMC a bit to keep IO - stable - -This drops to hs200 mode and 150Mhz as this is actually stable across -eMMC modules. There exist some that are incompatible at higher rates -with the rk3588 and to avoid your filesystem corrupting due to IO -errors, be more conservative and reduce the max. speed. - -Signed-off-by: Carsten Haitzler <raster@rasterman.com> -Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> ---- - arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts -index aed327526853..b8717606517c 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts -@@ -484,8 +484,8 @@ &sdhci { - no-sdio; - no-sd; - non-removable; -- mmc-hs400-1_8v; -- mmc-hs400-enhanced-strobe; -+ max-frequency = <150000000>; -+ mmc-hs200-1_8v; - status = "okay"; - }; - --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0016-vop2-Add-clock-resets-support.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0016-vop2-Add-clock-resets-support.patch deleted file mode 100644 index e36ec1ea42..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0016-vop2-Add-clock-resets-support.patch +++ /dev/null @@ -1,88 +0,0 @@ -From e40869fb0fd88749826d833468b66bd625662e89 Mon Sep 17 00:00:00 2001 -From: Detlev Casanova <detlev.casanova@collabora.com> -Date: Fri, 3 May 2024 14:27:39 -0400 -Subject: [PATCH 16/63] vop2: Add clock resets support - -At the end of initialization, each VP clock needs to be reset before -they can be used. - -Failing to do so can put the VOP in an undefined state where the -generated HDMI signal is either lost or not matching the selected mode. - -Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com> ---- - drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 30 ++++++++++++++++++++ - 1 file changed, 30 insertions(+) - -diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c -index 9873172e3fd3..6122eb18e6c9 100644 ---- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c -+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c -@@ -17,6 +17,7 @@ - #include <linux/platform_device.h> - #include <linux/pm_runtime.h> - #include <linux/regmap.h> -+#include <linux/reset.h> - #include <linux/swab.h> - - #include <drm/drm.h> -@@ -157,6 +158,7 @@ struct vop2_win { - struct vop2_video_port { - struct drm_crtc crtc; - struct vop2 *vop2; -+ struct reset_control *dclk_rst; - struct clk *dclk; - unsigned int id; - const struct vop2_video_port_data *data; -@@ -1917,6 +1919,26 @@ static int us_to_vertical_line(struct drm_display_mode *mode, int us) - return us * mode->clock / mode->htotal / 1000; - } - -+static int vop2_clk_reset(struct vop2_video_port *vp) -+{ -+ struct reset_control *rstc = vp->dclk_rst; -+ struct vop2 *vop2 = vp->vop2; -+ int ret; -+ -+ if (!rstc) -+ return 0; -+ -+ ret = reset_control_assert(rstc); -+ if (ret < 0) -+ drm_warn(vop2->drm, "failed to assert reset\n"); -+ udelay(10); -+ ret = reset_control_deassert(rstc); -+ if (ret < 0) -+ drm_warn(vop2->drm, "failed to deassert reset\n"); -+ -+ return ret; -+} -+ - static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_atomic_state *state) - { -@@ -2057,6 +2079,8 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, - - vop2_vp_write(vp, RK3568_VP_DSP_CTRL, dsp_ctrl); - -+ vop2_clk_reset(vp); -+ - drm_crtc_vblank_on(crtc); - - vop2_unlock(vop2); -@@ -2708,6 +2732,12 @@ static int vop2_create_crtcs(struct vop2 *vop2) - vp->data = vp_data; - - snprintf(dclk_name, sizeof(dclk_name), "dclk_vp%d", vp->id); -+ vp->dclk_rst = devm_reset_control_get_optional(vop2->dev, dclk_name); -+ if (IS_ERR(vp->dclk_rst)) { -+ drm_err(vop2->drm, "failed to get %s reset\n", dclk_name); -+ return PTR_ERR(vp->dclk_rst); -+ } -+ - 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); --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0017-arm64-dts-rockchip-Add-VOP-clock-resets-for-rk3588s.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0017-arm64-dts-rockchip-Add-VOP-clock-resets-for-rk3588s.patch deleted file mode 100644 index 1dd344f179..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0017-arm64-dts-rockchip-Add-VOP-clock-resets-for-rk3588s.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 9ce06de49b0adf8c8021d035cb2326ebd09e89f1 Mon Sep 17 00:00:00 2001 -From: Detlev Casanova <detlev.casanova@collabora.com> -Date: Fri, 3 May 2024 14:28:12 -0400 -Subject: [PATCH 17/63] arm64: dts: rockchip: Add VOP clock resets for rk3588s - -This adds the needed clock resets for all rk3588(s) based SOCs. - -Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com> ---- - arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi -index fc67585b64b7..11ad0487eaab 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi -@@ -1272,6 +1272,14 @@ vop: vop@fdd90000 { - "pclk_vop"; - iommus = <&vop_mmu>; - power-domains = <&power RK3588_PD_VOP>; -+ resets = <&cru SRST_D_VOP0>, -+ <&cru SRST_D_VOP1>, -+ <&cru SRST_D_VOP2>, -+ <&cru SRST_D_VOP3>; -+ reset-names = "dclk_vp0", -+ "dclk_vp1", -+ "dclk_vp2", -+ "dclk_vp3"; - rockchip,grf = <&sys_grf>; - rockchip,vop-grf = <&vop_grf>; - rockchip,vo1-grf = <&vo1_grf>; --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0018-dt-bindings-display-vop2-Add-VP-clock-resets.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0018-dt-bindings-display-vop2-Add-VP-clock-resets.patch deleted file mode 100644 index d43487cf94..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0018-dt-bindings-display-vop2-Add-VP-clock-resets.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 236dcd90be8abc26cc1007f35391e91d59654fa4 Mon Sep 17 00:00:00 2001 -From: Detlev Casanova <detlev.casanova@collabora.com> -Date: Mon, 6 May 2024 13:54:01 -0400 -Subject: [PATCH 18/63] dt-bindings: display: vop2: Add VP clock resets - -Add the documentation for VOP2 video ports reset clocks. -One reset can be set per video port. - -Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com> ---- - .../display/rockchip/rockchip-vop2.yaml | 27 +++++++++++++++++++ - 1 file changed, 27 insertions(+) - -diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml -index 2531726af306..941fd059498d 100644 ---- a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml -+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml -@@ -65,6 +65,22 @@ properties: - - const: dclk_vp3 - - const: pclk_vop - -+ resets: -+ minItems: 3 -+ items: -+ - description: Pixel clock reset for video port 0. -+ - description: Pixel clock reset for video port 1. -+ - description: Pixel clock reset for video port 2. -+ - description: Pixel clock reset for video port 3. -+ -+ reset-names: -+ minItems: 3 -+ items: -+ - const: dclk_vp0 -+ - const: dclk_vp1 -+ - const: dclk_vp2 -+ - const: dclk_vp3 -+ - rockchip,grf: - $ref: /schemas/types.yaml#/definitions/phandle - description: -@@ -128,6 +144,11 @@ allOf: - clock-names: - minItems: 7 - -+ resets: -+ minItems: 4 -+ reset-names: -+ minItems: 4 -+ - ports: - required: - - port@0 -@@ -183,6 +204,12 @@ examples: - "dclk_vp0", - "dclk_vp1", - "dclk_vp2"; -+ resets = <&cru SRST_VOP0>, -+ <&cru SRST_VOP1>, -+ <&cru SRST_VOP2>; -+ reset-names = "dclk_vp0", -+ "dclk_vp1", -+ "dclk_vp2"; - power-domains = <&power RK3568_PD_VO>; - iommus = <&vop_mmu>; - vop_out: ports { --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0019-media-v4l2-ctrls-core-Set-frame_mbs_only_flag-by-def.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0019-media-v4l2-ctrls-core-Set-frame_mbs_only_flag-by-def.patch deleted file mode 100644 index 2fe60b795e..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0019-media-v4l2-ctrls-core-Set-frame_mbs_only_flag-by-def.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 27baa3488776c3678dee463afda1a09a8325ef02 Mon Sep 17 00:00:00 2001 -From: Detlev Casanova <detlev.casanova@collabora.com> -Date: Thu, 27 Jun 2024 09:42:12 -0400 -Subject: [PATCH 19/63] media: v4l2-ctrls-core: Set frame_mbs_only_flag by - default in h264 SPS - -This flag is needed for drivers that have a minimum height lower -than 32 pixels. - -This is because when the flag is not set, the height is halved, which -would make it lower than 16 pixels if min height is 16. - -Setting this flag will keep the height at its value and have a valid -SPS. - -Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com> ---- - drivers/media/v4l2-core/v4l2-ctrls-core.c | 13 +++++++++++++ - 1 file changed, 13 insertions(+) - -diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c b/drivers/media/v4l2-core/v4l2-ctrls-core.c -index eeab6a5eb7ba..e98eee19bd4d 100644 ---- a/drivers/media/v4l2-core/v4l2-ctrls-core.c -+++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c -@@ -111,6 +111,7 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx, - struct v4l2_ctrl_vp9_frame *p_vp9_frame; - struct v4l2_ctrl_fwht_params *p_fwht_params; - struct v4l2_ctrl_h264_scaling_matrix *p_h264_scaling_matrix; -+ struct v4l2_ctrl_h264_sps *p_h264_sps; - struct v4l2_ctrl_av1_sequence *p_av1_sequence; - void *p = ptr.p + idx * ctrl->elem_size; - -@@ -179,6 +180,18 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx, - */ - memset(p_h264_scaling_matrix, 16, sizeof(*p_h264_scaling_matrix)); - break; -+ case V4L2_CTRL_TYPE_H264_SPS: -+ p_h264_sps = p; -+ /* -+ * Without V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY, -+ * frame_mbs_only_flag set to 0 will translate to a miniumum -+ * height of 32 (see H.264 specification 7-8). Some driver may -+ * have a minimum size lower than 32, which would fail -+ * validation with the SPS value. Set this flag, so that there -+ * is now doubling in the height, allowing a valid default. -+ */ -+ p_h264_sps->flags = V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY; -+ break; - } - } - --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0020-media-rockchip-Move-H264-CABAC-table-to-header-file.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0020-media-rockchip-Move-H264-CABAC-table-to-header-file.patch deleted file mode 100644 index 455c1d8be9..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0020-media-rockchip-Move-H264-CABAC-table-to-header-file.patch +++ /dev/null @@ -1,1056 +0,0 @@ -From 5edb726ac38053ff9d28ab3d5004982d5cc115ba Mon Sep 17 00:00:00 2001 -From: Detlev Casanova <detlev.casanova@collabora.com> -Date: Tue, 18 Jun 2024 12:41:51 -0400 -Subject: [PATCH 20/63] media: rockchip: Move H264 CABAC table to header file - -The table will be shared with the rkvdec2 driver in following commits. - -As HW formatted CABAC tables can be shared between drivers, it makes sense -to group them in an include folder. - -Each driver can include the tables they need so that all tables are not -built in the kernel, but rather in each driver, if the driver is enabled. - -Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com> ---- - drivers/staging/media/rkvdec/rkvdec-h264.c | 500 +------------------- - include/media/v4l2-cabac/rkvdec-cabac.h | 509 +++++++++++++++++++++ - 2 files changed, 510 insertions(+), 499 deletions(-) - create mode 100644 include/media/v4l2-cabac/rkvdec-cabac.h - -diff --git a/drivers/staging/media/rkvdec/rkvdec-h264.c b/drivers/staging/media/rkvdec/rkvdec-h264.c -index 4fc167b42cf0..ce63b6fbaa33 100644 ---- a/drivers/staging/media/rkvdec/rkvdec-h264.c -+++ b/drivers/staging/media/rkvdec/rkvdec-h264.c -@@ -11,6 +11,7 @@ - - #include <media/v4l2-h264.h> - #include <media/v4l2-mem2mem.h> -+#include <media/v4l2-cabac/rkvdec-cabac.h> - - #include "rkvdec.h" - #include "rkvdec-regs.h" -@@ -117,505 +118,6 @@ struct rkvdec_h264_ctx { - struct rkvdec_h264_reflists reflists; - }; - --#define CABAC_ENTRY(ctxidx, idc0_m, idc0_n, idc1_m, idc1_n, \ -- idc2_m, idc2_n, intra_m, intra_n) \ -- [0][(ctxidx)] = {idc0_m, idc0_n}, \ -- [1][(ctxidx)] = {idc1_m, idc1_n}, \ -- [2][(ctxidx)] = {idc2_m, idc2_n}, \ -- [3][(ctxidx)] = {intra_m, intra_n} -- --/* -- * Constant CABAC table. -- * Built from the tables described in section '9.3.1.1 Initialisation process -- * for context variables' of the H264 spec. -- */ --static const s8 rkvdec_h264_cabac_table[4][464][2] = { -- /* Table 9-12 – Values of variables m and n for ctxIdx from 0 to 10 */ -- CABAC_ENTRY(0, 20, -15, 20, -15, 20, -15, 20, -15), -- CABAC_ENTRY(1, 2, 54, 2, 54, 2, 54, 2, 54), -- CABAC_ENTRY(2, 3, 74, 3, 74, 3, 74, 3, 74), -- CABAC_ENTRY(3, 20, -15, 20, -15, 20, -15, 20, -15), -- CABAC_ENTRY(4, 2, 54, 2, 54, 2, 54, 2, 54), -- CABAC_ENTRY(5, 3, 74, 3, 74, 3, 74, 3, 74), -- CABAC_ENTRY(6, -28, 127, -28, 127, -28, 127, -28, 127), -- CABAC_ENTRY(7, -23, 104, -23, 104, -23, 104, -23, 104), -- CABAC_ENTRY(8, -6, 53, -6, 53, -6, 53, -6, 53), -- CABAC_ENTRY(9, -1, 54, -1, 54, -1, 54, -1, 54), -- CABAC_ENTRY(10, 7, 51, 7, 51, 7, 51, 7, 51), -- -- /* Table 9-13 – Values of variables m and n for ctxIdx from 11 to 23 */ -- CABAC_ENTRY(11, 23, 33, 22, 25, 29, 16, 0, 0), -- CABAC_ENTRY(12, 23, 2, 34, 0, 25, 0, 0, 0), -- CABAC_ENTRY(13, 21, 0, 16, 0, 14, 0, 0, 0), -- CABAC_ENTRY(14, 1, 9, -2, 9, -10, 51, 0, 0), -- CABAC_ENTRY(15, 0, 49, 4, 41, -3, 62, 0, 0), -- CABAC_ENTRY(16, -37, 118, -29, 118, -27, 99, 0, 0), -- CABAC_ENTRY(17, 5, 57, 2, 65, 26, 16, 0, 0), -- CABAC_ENTRY(18, -13, 78, -6, 71, -4, 85, 0, 0), -- CABAC_ENTRY(19, -11, 65, -13, 79, -24, 102, 0, 0), -- CABAC_ENTRY(20, 1, 62, 5, 52, 5, 57, 0, 0), -- CABAC_ENTRY(21, 12, 49, 9, 50, 6, 57, 0, 0), -- CABAC_ENTRY(22, -4, 73, -3, 70, -17, 73, 0, 0), -- CABAC_ENTRY(23, 17, 50, 10, 54, 14, 57, 0, 0), -- -- /* Table 9-14 – Values of variables m and n for ctxIdx from 24 to 39 */ -- CABAC_ENTRY(24, 18, 64, 26, 34, 20, 40, 0, 0), -- CABAC_ENTRY(25, 9, 43, 19, 22, 20, 10, 0, 0), -- CABAC_ENTRY(26, 29, 0, 40, 0, 29, 0, 0, 0), -- CABAC_ENTRY(27, 26, 67, 57, 2, 54, 0, 0, 0), -- CABAC_ENTRY(28, 16, 90, 41, 36, 37, 42, 0, 0), -- CABAC_ENTRY(29, 9, 104, 26, 69, 12, 97, 0, 0), -- CABAC_ENTRY(30, -46, 127, -45, 127, -32, 127, 0, 0), -- CABAC_ENTRY(31, -20, 104, -15, 101, -22, 117, 0, 0), -- CABAC_ENTRY(32, 1, 67, -4, 76, -2, 74, 0, 0), -- CABAC_ENTRY(33, -13, 78, -6, 71, -4, 85, 0, 0), -- CABAC_ENTRY(34, -11, 65, -13, 79, -24, 102, 0, 0), -- CABAC_ENTRY(35, 1, 62, 5, 52, 5, 57, 0, 0), -- CABAC_ENTRY(36, -6, 86, 6, 69, -6, 93, 0, 0), -- CABAC_ENTRY(37, -17, 95, -13, 90, -14, 88, 0, 0), -- CABAC_ENTRY(38, -6, 61, 0, 52, -6, 44, 0, 0), -- CABAC_ENTRY(39, 9, 45, 8, 43, 4, 55, 0, 0), -- -- /* Table 9-15 – Values of variables m and n for ctxIdx from 40 to 53 */ -- CABAC_ENTRY(40, -3, 69, -2, 69, -11, 89, 0, 0), -- CABAC_ENTRY(41, -6, 81, -5, 82, -15, 103, 0, 0), -- CABAC_ENTRY(42, -11, 96, -10, 96, -21, 116, 0, 0), -- CABAC_ENTRY(43, 6, 55, 2, 59, 19, 57, 0, 0), -- CABAC_ENTRY(44, 7, 67, 2, 75, 20, 58, 0, 0), -- CABAC_ENTRY(45, -5, 86, -3, 87, 4, 84, 0, 0), -- CABAC_ENTRY(46, 2, 88, -3, 100, 6, 96, 0, 0), -- CABAC_ENTRY(47, 0, 58, 1, 56, 1, 63, 0, 0), -- CABAC_ENTRY(48, -3, 76, -3, 74, -5, 85, 0, 0), -- CABAC_ENTRY(49, -10, 94, -6, 85, -13, 106, 0, 0), -- CABAC_ENTRY(50, 5, 54, 0, 59, 5, 63, 0, 0), -- CABAC_ENTRY(51, 4, 69, -3, 81, 6, 75, 0, 0), -- CABAC_ENTRY(52, -3, 81, -7, 86, -3, 90, 0, 0), -- CABAC_ENTRY(53, 0, 88, -5, 95, -1, 101, 0, 0), -- -- /* Table 9-16 – Values of variables m and n for ctxIdx from 54 to 59 */ -- CABAC_ENTRY(54, -7, 67, -1, 66, 3, 55, 0, 0), -- CABAC_ENTRY(55, -5, 74, -1, 77, -4, 79, 0, 0), -- CABAC_ENTRY(56, -4, 74, 1, 70, -2, 75, 0, 0), -- CABAC_ENTRY(57, -5, 80, -2, 86, -12, 97, 0, 0), -- CABAC_ENTRY(58, -7, 72, -5, 72, -7, 50, 0, 0), -- CABAC_ENTRY(59, 1, 58, 0, 61, 1, 60, 0, 0), -- -- /* Table 9-17 – Values of variables m and n for ctxIdx from 60 to 69 */ -- CABAC_ENTRY(60, 0, 41, 0, 41, 0, 41, 0, 41), -- CABAC_ENTRY(61, 0, 63, 0, 63, 0, 63, 0, 63), -- CABAC_ENTRY(62, 0, 63, 0, 63, 0, 63, 0, 63), -- CABAC_ENTRY(63, 0, 63, 0, 63, 0, 63, 0, 63), -- CABAC_ENTRY(64, -9, 83, -9, 83, -9, 83, -9, 83), -- CABAC_ENTRY(65, 4, 86, 4, 86, 4, 86, 4, 86), -- CABAC_ENTRY(66, 0, 97, 0, 97, 0, 97, 0, 97), -- CABAC_ENTRY(67, -7, 72, -7, 72, -7, 72, -7, 72), -- CABAC_ENTRY(68, 13, 41, 13, 41, 13, 41, 13, 41), -- CABAC_ENTRY(69, 3, 62, 3, 62, 3, 62, 3, 62), -- -- /* Table 9-18 – Values of variables m and n for ctxIdx from 70 to 104 */ -- CABAC_ENTRY(70, 0, 45, 13, 15, 7, 34, 0, 11), -- CABAC_ENTRY(71, -4, 78, 7, 51, -9, 88, 1, 55), -- CABAC_ENTRY(72, -3, 96, 2, 80, -20, 127, 0, 69), -- CABAC_ENTRY(73, -27, 126, -39, 127, -36, 127, -17, 127), -- CABAC_ENTRY(74, -28, 98, -18, 91, -17, 91, -13, 102), -- CABAC_ENTRY(75, -25, 101, -17, 96, -14, 95, 0, 82), -- CABAC_ENTRY(76, -23, 67, -26, 81, -25, 84, -7, 74), -- CABAC_ENTRY(77, -28, 82, -35, 98, -25, 86, -21, 107), -- CABAC_ENTRY(78, -20, 94, -24, 102, -12, 89, -27, 127), -- CABAC_ENTRY(79, -16, 83, -23, 97, -17, 91, -31, 127), -- CABAC_ENTRY(80, -22, 110, -27, 119, -31, 127, -24, 127), -- CABAC_ENTRY(81, -21, 91, -24, 99, -14, 76, -18, 95), -- CABAC_ENTRY(82, -18, 102, -21, 110, -18, 103, -27, 127), -- CABAC_ENTRY(83, -13, 93, -18, 102, -13, 90, -21, 114), -- CABAC_ENTRY(84, -29, 127, -36, 127, -37, 127, -30, 127), -- CABAC_ENTRY(85, -7, 92, 0, 80, 11, 80, -17, 123), -- CABAC_ENTRY(86, -5, 89, -5, 89, 5, 76, -12, 115), -- CABAC_ENTRY(87, -7, 96, -7, 94, 2, 84, -16, 122), -- CABAC_ENTRY(88, -13, 108, -4, 92, 5, 78, -11, 115), -- CABAC_ENTRY(89, -3, 46, 0, 39, -6, 55, -12, 63), -- CABAC_ENTRY(90, -1, 65, 0, 65, 4, 61, -2, 68), -- CABAC_ENTRY(91, -1, 57, -15, 84, -14, 83, -15, 84), -- CABAC_ENTRY(92, -9, 93, -35, 127, -37, 127, -13, 104), -- CABAC_ENTRY(93, -3, 74, -2, 73, -5, 79, -3, 70), -- CABAC_ENTRY(94, -9, 92, -12, 104, -11, 104, -8, 93), -- CABAC_ENTRY(95, -8, 87, -9, 91, -11, 91, -10, 90), -- CABAC_ENTRY(96, -23, 126, -31, 127, -30, 127, -30, 127), -- CABAC_ENTRY(97, 5, 54, 3, 55, 0, 65, -1, 74), -- CABAC_ENTRY(98, 6, 60, 7, 56, -2, 79, -6, 97), -- CABAC_ENTRY(99, 6, 59, 7, 55, 0, 72, -7, 91), -- CABAC_ENTRY(100, 6, 69, 8, 61, -4, 92, -20, 127), -- CABAC_ENTRY(101, -1, 48, -3, 53, -6, 56, -4, 56), -- CABAC_ENTRY(102, 0, 68, 0, 68, 3, 68, -5, 82), -- CABAC_ENTRY(103, -4, 69, -7, 74, -8, 71, -7, 76), -- CABAC_ENTRY(104, -8, 88, -9, 88, -13, 98, -22, 125), -- -- /* Table 9-19 – Values of variables m and n for ctxIdx from 105 to 165 */ -- CABAC_ENTRY(105, -2, 85, -13, 103, -4, 86, -7, 93), -- CABAC_ENTRY(106, -6, 78, -13, 91, -12, 88, -11, 87), -- CABAC_ENTRY(107, -1, 75, -9, 89, -5, 82, -3, 77), -- CABAC_ENTRY(108, -7, 77, -14, 92, -3, 72, -5, 71), -- CABAC_ENTRY(109, 2, 54, -8, 76, -4, 67, -4, 63), -- CABAC_ENTRY(110, 5, 50, -12, 87, -8, 72, -4, 68), -- CABAC_ENTRY(111, -3, 68, -23, 110, -16, 89, -12, 84), -- CABAC_ENTRY(112, 1, 50, -24, 105, -9, 69, -7, 62), -- CABAC_ENTRY(113, 6, 42, -10, 78, -1, 59, -7, 65), -- CABAC_ENTRY(114, -4, 81, -20, 112, 5, 66, 8, 61), -- CABAC_ENTRY(115, 1, 63, -17, 99, 4, 57, 5, 56), -- CABAC_ENTRY(116, -4, 70, -78, 127, -4, 71, -2, 66), -- CABAC_ENTRY(117, 0, 67, -70, 127, -2, 71, 1, 64), -- CABAC_ENTRY(118, 2, 57, -50, 127, 2, 58, 0, 61), -- CABAC_ENTRY(119, -2, 76, -46, 127, -1, 74, -2, 78), -- CABAC_ENTRY(120, 11, 35, -4, 66, -4, 44, 1, 50), -- CABAC_ENTRY(121, 4, 64, -5, 78, -1, 69, 7, 52), -- CABAC_ENTRY(122, 1, 61, -4, 71, 0, 62, 10, 35), -- CABAC_ENTRY(123, 11, 35, -8, 72, -7, 51, 0, 44), -- CABAC_ENTRY(124, 18, 25, 2, 59, -4, 47, 11, 38), -- CABAC_ENTRY(125, 12, 24, -1, 55, -6, 42, 1, 45), -- CABAC_ENTRY(126, 13, 29, -7, 70, -3, 41, 0, 46), -- CABAC_ENTRY(127, 13, 36, -6, 75, -6, 53, 5, 44), -- CABAC_ENTRY(128, -10, 93, -8, 89, 8, 76, 31, 17), -- CABAC_ENTRY(129, -7, 73, -34, 119, -9, 78, 1, 51), -- CABAC_ENTRY(130, -2, 73, -3, 75, -11, 83, 7, 50), -- CABAC_ENTRY(131, 13, 46, 32, 20, 9, 52, 28, 19), -- CABAC_ENTRY(132, 9, 49, 30, 22, 0, 67, 16, 33), -- CABAC_ENTRY(133, -7, 100, -44, 127, -5, 90, 14, 62), -- CABAC_ENTRY(134, 9, 53, 0, 54, 1, 67, -13, 108), -- CABAC_ENTRY(135, 2, 53, -5, 61, -15, 72, -15, 100), -- CABAC_ENTRY(136, 5, 53, 0, 58, -5, 75, -13, 101), -- CABAC_ENTRY(137, -2, 61, -1, 60, -8, 80, -13, 91), -- CABAC_ENTRY(138, 0, 56, -3, 61, -21, 83, -12, 94), -- CABAC_ENTRY(139, 0, 56, -8, 67, -21, 64, -10, 88), -- CABAC_ENTRY(140, -13, 63, -25, 84, -13, 31, -16, 84), -- CABAC_ENTRY(141, -5, 60, -14, 74, -25, 64, -10, 86), -- CABAC_ENTRY(142, -1, 62, -5, 65, -29, 94, -7, 83), -- CABAC_ENTRY(143, 4, 57, 5, 52, 9, 75, -13, 87), -- CABAC_ENTRY(144, -6, 69, 2, 57, 17, 63, -19, 94), -- CABAC_ENTRY(145, 4, 57, 0, 61, -8, 74, 1, 70), -- CABAC_ENTRY(146, 14, 39, -9, 69, -5, 35, 0, 72), -- CABAC_ENTRY(147, 4, 51, -11, 70, -2, 27, -5, 74), -- CABAC_ENTRY(148, 13, 68, 18, 55, 13, 91, 18, 59), -- CABAC_ENTRY(149, 3, 64, -4, 71, 3, 65, -8, 102), -- CABAC_ENTRY(150, 1, 61, 0, 58, -7, 69, -15, 100), -- CABAC_ENTRY(151, 9, 63, 7, 61, 8, 77, 0, 95), -- CABAC_ENTRY(152, 7, 50, 9, 41, -10, 66, -4, 75), -- CABAC_ENTRY(153, 16, 39, 18, 25, 3, 62, 2, 72), -- CABAC_ENTRY(154, 5, 44, 9, 32, -3, 68, -11, 75), -- CABAC_ENTRY(155, 4, 52, 5, 43, -20, 81, -3, 71), -- CABAC_ENTRY(156, 11, 48, 9, 47, 0, 30, 15, 46), -- CABAC_ENTRY(157, -5, 60, 0, 44, 1, 7, -13, 69), -- CABAC_ENTRY(158, -1, 59, 0, 51, -3, 23, 0, 62), -- CABAC_ENTRY(159, 0, 59, 2, 46, -21, 74, 0, 65), -- CABAC_ENTRY(160, 22, 33, 19, 38, 16, 66, 21, 37), -- CABAC_ENTRY(161, 5, 44, -4, 66, -23, 124, -15, 72), -- CABAC_ENTRY(162, 14, 43, 15, 38, 17, 37, 9, 57), -- CABAC_ENTRY(163, -1, 78, 12, 42, 44, -18, 16, 54), -- CABAC_ENTRY(164, 0, 60, 9, 34, 50, -34, 0, 62), -- CABAC_ENTRY(165, 9, 69, 0, 89, -22, 127, 12, 72), -- -- /* Table 9-20 – Values of variables m and n for ctxIdx from 166 to 226 */ -- CABAC_ENTRY(166, 11, 28, 4, 45, 4, 39, 24, 0), -- CABAC_ENTRY(167, 2, 40, 10, 28, 0, 42, 15, 9), -- CABAC_ENTRY(168, 3, 44, 10, 31, 7, 34, 8, 25), -- CABAC_ENTRY(169, 0, 49, 33, -11, 11, 29, 13, 18), -- CABAC_ENTRY(170, 0, 46, 52, -43, 8, 31, 15, 9), -- CABAC_ENTRY(171, 2, 44, 18, 15, 6, 37, 13, 19), -- CABAC_ENTRY(172, 2, 51, 28, 0, 7, 42, 10, 37), -- CABAC_ENTRY(173, 0, 47, 35, -22, 3, 40, 12, 18), -- CABAC_ENTRY(174, 4, 39, 38, -25, 8, 33, 6, 29), -- CABAC_ENTRY(175, 2, 62, 34, 0, 13, 43, 20, 33), -- CABAC_ENTRY(176, 6, 46, 39, -18, 13, 36, 15, 30), -- CABAC_ENTRY(177, 0, 54, 32, -12, 4, 47, 4, 45), -- CABAC_ENTRY(178, 3, 54, 102, -94, 3, 55, 1, 58), -- CABAC_ENTRY(179, 2, 58, 0, 0, 2, 58, 0, 62), -- CABAC_ENTRY(180, 4, 63, 56, -15, 6, 60, 7, 61), -- CABAC_ENTRY(181, 6, 51, 33, -4, 8, 44, 12, 38), -- CABAC_ENTRY(182, 6, 57, 29, 10, 11, 44, 11, 45), -- CABAC_ENTRY(183, 7, 53, 37, -5, 14, 42, 15, 39), -- CABAC_ENTRY(184, 6, 52, 51, -29, 7, 48, 11, 42), -- CABAC_ENTRY(185, 6, 55, 39, -9, 4, 56, 13, 44), -- CABAC_ENTRY(186, 11, 45, 52, -34, 4, 52, 16, 45), -- CABAC_ENTRY(187, 14, 36, 69, -58, 13, 37, 12, 41), -- CABAC_ENTRY(188, 8, 53, 67, -63, 9, 49, 10, 49), -- CABAC_ENTRY(189, -1, 82, 44, -5, 19, 58, 30, 34), -- CABAC_ENTRY(190, 7, 55, 32, 7, 10, 48, 18, 42), -- CABAC_ENTRY(191, -3, 78, 55, -29, 12, 45, 10, 55), -- CABAC_ENTRY(192, 15, 46, 32, 1, 0, 69, 17, 51), -- CABAC_ENTRY(193, 22, 31, 0, 0, 20, 33, 17, 46), -- CABAC_ENTRY(194, -1, 84, 27, 36, 8, 63, 0, 89), -- CABAC_ENTRY(195, 25, 7, 33, -25, 35, -18, 26, -19), -- CABAC_ENTRY(196, 30, -7, 34, -30, 33, -25, 22, -17), -- CABAC_ENTRY(197, 28, 3, 36, -28, 28, -3, 26, -17), -- CABAC_ENTRY(198, 28, 4, 38, -28, 24, 10, 30, -25), -- CABAC_ENTRY(199, 32, 0, 38, -27, 27, 0, 28, -20), -- CABAC_ENTRY(200, 34, -1, 34, -18, 34, -14, 33, -23), -- CABAC_ENTRY(201, 30, 6, 35, -16, 52, -44, 37, -27), -- CABAC_ENTRY(202, 30, 6, 34, -14, 39, -24, 33, -23), -- CABAC_ENTRY(203, 32, 9, 32, -8, 19, 17, 40, -28), -- CABAC_ENTRY(204, 31, 19, 37, -6, 31, 25, 38, -17), -- CABAC_ENTRY(205, 26, 27, 35, 0, 36, 29, 33, -11), -- CABAC_ENTRY(206, 26, 30, 30, 10, 24, 33, 40, -15), -- CABAC_ENTRY(207, 37, 20, 28, 18, 34, 15, 41, -6), -- CABAC_ENTRY(208, 28, 34, 26, 25, 30, 20, 38, 1), -- CABAC_ENTRY(209, 17, 70, 29, 41, 22, 73, 41, 17), -- CABAC_ENTRY(210, 1, 67, 0, 75, 20, 34, 30, -6), -- CABAC_ENTRY(211, 5, 59, 2, 72, 19, 31, 27, 3), -- CABAC_ENTRY(212, 9, 67, 8, 77, 27, 44, 26, 22), -- CABAC_ENTRY(213, 16, 30, 14, 35, 19, 16, 37, -16), -- CABAC_ENTRY(214, 18, 32, 18, 31, 15, 36, 35, -4), -- CABAC_ENTRY(215, 18, 35, 17, 35, 15, 36, 38, -8), -- CABAC_ENTRY(216, 22, 29, 21, 30, 21, 28, 38, -3), -- CABAC_ENTRY(217, 24, 31, 17, 45, 25, 21, 37, 3), -- CABAC_ENTRY(218, 23, 38, 20, 42, 30, 20, 38, 5), -- CABAC_ENTRY(219, 18, 43, 18, 45, 31, 12, 42, 0), -- CABAC_ENTRY(220, 20, 41, 27, 26, 27, 16, 35, 16), -- CABAC_ENTRY(221, 11, 63, 16, 54, 24, 42, 39, 22), -- CABAC_ENTRY(222, 9, 59, 7, 66, 0, 93, 14, 48), -- CABAC_ENTRY(223, 9, 64, 16, 56, 14, 56, 27, 37), -- CABAC_ENTRY(224, -1, 94, 11, 73, 15, 57, 21, 60), -- CABAC_ENTRY(225, -2, 89, 10, 67, 26, 38, 12, 68), -- CABAC_ENTRY(226, -9, 108, -10, 116, -24, 127, 2, 97), -- -- /* Table 9-21 – Values of variables m and n for ctxIdx from 227 to 275 */ -- CABAC_ENTRY(227, -6, 76, -23, 112, -24, 115, -3, 71), -- CABAC_ENTRY(228, -2, 44, -15, 71, -22, 82, -6, 42), -- CABAC_ENTRY(229, 0, 45, -7, 61, -9, 62, -5, 50), -- CABAC_ENTRY(230, 0, 52, 0, 53, 0, 53, -3, 54), -- CABAC_ENTRY(231, -3, 64, -5, 66, 0, 59, -2, 62), -- CABAC_ENTRY(232, -2, 59, -11, 77, -14, 85, 0, 58), -- CABAC_ENTRY(233, -4, 70, -9, 80, -13, 89, 1, 63), -- CABAC_ENTRY(234, -4, 75, -9, 84, -13, 94, -2, 72), -- CABAC_ENTRY(235, -8, 82, -10, 87, -11, 92, -1, 74), -- CABAC_ENTRY(236, -17, 102, -34, 127, -29, 127, -9, 91), -- CABAC_ENTRY(237, -9, 77, -21, 101, -21, 100, -5, 67), -- CABAC_ENTRY(238, 3, 24, -3, 39, -14, 57, -5, 27), -- CABAC_ENTRY(239, 0, 42, -5, 53, -12, 67, -3, 39), -- CABAC_ENTRY(240, 0, 48, -7, 61, -11, 71, -2, 44), -- CABAC_ENTRY(241, 0, 55, -11, 75, -10, 77, 0, 46), -- CABAC_ENTRY(242, -6, 59, -15, 77, -21, 85, -16, 64), -- CABAC_ENTRY(243, -7, 71, -17, 91, -16, 88, -8, 68), -- CABAC_ENTRY(244, -12, 83, -25, 107, -23, 104, -10, 78), -- CABAC_ENTRY(245, -11, 87, -25, 111, -15, 98, -6, 77), -- CABAC_ENTRY(246, -30, 119, -28, 122, -37, 127, -10, 86), -- CABAC_ENTRY(247, 1, 58, -11, 76, -10, 82, -12, 92), -- CABAC_ENTRY(248, -3, 29, -10, 44, -8, 48, -15, 55), -- CABAC_ENTRY(249, -1, 36, -10, 52, -8, 61, -10, 60), -- CABAC_ENTRY(250, 1, 38, -10, 57, -8, 66, -6, 62), -- CABAC_ENTRY(251, 2, 43, -9, 58, -7, 70, -4, 65), -- CABAC_ENTRY(252, -6, 55, -16, 72, -14, 75, -12, 73), -- CABAC_ENTRY(253, 0, 58, -7, 69, -10, 79, -8, 76), -- CABAC_ENTRY(254, 0, 64, -4, 69, -9, 83, -7, 80), -- CABAC_ENTRY(255, -3, 74, -5, 74, -12, 92, -9, 88), -- CABAC_ENTRY(256, -10, 90, -9, 86, -18, 108, -17, 110), -- CABAC_ENTRY(257, 0, 70, 2, 66, -4, 79, -11, 97), -- CABAC_ENTRY(258, -4, 29, -9, 34, -22, 69, -20, 84), -- CABAC_ENTRY(259, 5, 31, 1, 32, -16, 75, -11, 79), -- CABAC_ENTRY(260, 7, 42, 11, 31, -2, 58, -6, 73), -- CABAC_ENTRY(261, 1, 59, 5, 52, 1, 58, -4, 74), -- CABAC_ENTRY(262, -2, 58, -2, 55, -13, 78, -13, 86), -- CABAC_ENTRY(263, -3, 72, -2, 67, -9, 83, -13, 96), -- CABAC_ENTRY(264, -3, 81, 0, 73, -4, 81, -11, 97), -- CABAC_ENTRY(265, -11, 97, -8, 89, -13, 99, -19, 117), -- CABAC_ENTRY(266, 0, 58, 3, 52, -13, 81, -8, 78), -- CABAC_ENTRY(267, 8, 5, 7, 4, -6, 38, -5, 33), -- CABAC_ENTRY(268, 10, 14, 10, 8, -13, 62, -4, 48), -- CABAC_ENTRY(269, 14, 18, 17, 8, -6, 58, -2, 53), -- CABAC_ENTRY(270, 13, 27, 16, 19, -2, 59, -3, 62), -- CABAC_ENTRY(271, 2, 40, 3, 37, -16, 73, -13, 71), -- CABAC_ENTRY(272, 0, 58, -1, 61, -10, 76, -10, 79), -- CABAC_ENTRY(273, -3, 70, -5, 73, -13, 86, -12, 86), -- CABAC_ENTRY(274, -6, 79, -1, 70, -9, 83, -13, 90), -- CABAC_ENTRY(275, -8, 85, -4, 78, -10, 87, -14, 97), -- -- /* Table 9-22 – Values of variables m and n for ctxIdx from 277 to 337 */ -- CABAC_ENTRY(277, -13, 106, -21, 126, -22, 127, -6, 93), -- CABAC_ENTRY(278, -16, 106, -23, 124, -25, 127, -6, 84), -- CABAC_ENTRY(279, -10, 87, -20, 110, -25, 120, -8, 79), -- CABAC_ENTRY(280, -21, 114, -26, 126, -27, 127, 0, 66), -- CABAC_ENTRY(281, -18, 110, -25, 124, -19, 114, -1, 71), -- CABAC_ENTRY(282, -14, 98, -17, 105, -23, 117, 0, 62), -- CABAC_ENTRY(283, -22, 110, -27, 121, -25, 118, -2, 60), -- CABAC_ENTRY(284, -21, 106, -27, 117, -26, 117, -2, 59), -- CABAC_ENTRY(285, -18, 103, -17, 102, -24, 113, -5, 75), -- CABAC_ENTRY(286, -21, 107, -26, 117, -28, 118, -3, 62), -- CABAC_ENTRY(287, -23, 108, -27, 116, -31, 120, -4, 58), -- CABAC_ENTRY(288, -26, 112, -33, 122, -37, 124, -9, 66), -- CABAC_ENTRY(289, -10, 96, -10, 95, -10, 94, -1, 79), -- CABAC_ENTRY(290, -12, 95, -14, 100, -15, 102, 0, 71), -- CABAC_ENTRY(291, -5, 91, -8, 95, -10, 99, 3, 68), -- CABAC_ENTRY(292, -9, 93, -17, 111, -13, 106, 10, 44), -- CABAC_ENTRY(293, -22, 94, -28, 114, -50, 127, -7, 62), -- CABAC_ENTRY(294, -5, 86, -6, 89, -5, 92, 15, 36), -- CABAC_ENTRY(295, 9, 67, -2, 80, 17, 57, 14, 40), -- CABAC_ENTRY(296, -4, 80, -4, 82, -5, 86, 16, 27), -- CABAC_ENTRY(297, -10, 85, -9, 85, -13, 94, 12, 29), -- CABAC_ENTRY(298, -1, 70, -8, 81, -12, 91, 1, 44), -- CABAC_ENTRY(299, 7, 60, -1, 72, -2, 77, 20, 36), -- CABAC_ENTRY(300, 9, 58, 5, 64, 0, 71, 18, 32), -- CABAC_ENTRY(301, 5, 61, 1, 67, -1, 73, 5, 42), -- CABAC_ENTRY(302, 12, 50, 9, 56, 4, 64, 1, 48), -- CABAC_ENTRY(303, 15, 50, 0, 69, -7, 81, 10, 62), -- CABAC_ENTRY(304, 18, 49, 1, 69, 5, 64, 17, 46), -- CABAC_ENTRY(305, 17, 54, 7, 69, 15, 57, 9, 64), -- CABAC_ENTRY(306, 10, 41, -7, 69, 1, 67, -12, 104), -- CABAC_ENTRY(307, 7, 46, -6, 67, 0, 68, -11, 97), -- CABAC_ENTRY(308, -1, 51, -16, 77, -10, 67, -16, 96), -- CABAC_ENTRY(309, 7, 49, -2, 64, 1, 68, -7, 88), -- CABAC_ENTRY(310, 8, 52, 2, 61, 0, 77, -8, 85), -- CABAC_ENTRY(311, 9, 41, -6, 67, 2, 64, -7, 85), -- CABAC_ENTRY(312, 6, 47, -3, 64, 0, 68, -9, 85), -- CABAC_ENTRY(313, 2, 55, 2, 57, -5, 78, -13, 88), -- CABAC_ENTRY(314, 13, 41, -3, 65, 7, 55, 4, 66), -- CABAC_ENTRY(315, 10, 44, -3, 66, 5, 59, -3, 77), -- CABAC_ENTRY(316, 6, 50, 0, 62, 2, 65, -3, 76), -- CABAC_ENTRY(317, 5, 53, 9, 51, 14, 54, -6, 76), -- CABAC_ENTRY(318, 13, 49, -1, 66, 15, 44, 10, 58), -- CABAC_ENTRY(319, 4, 63, -2, 71, 5, 60, -1, 76), -- CABAC_ENTRY(320, 6, 64, -2, 75, 2, 70, -1, 83), -- CABAC_ENTRY(321, -2, 69, -1, 70, -2, 76, -7, 99), -- CABAC_ENTRY(322, -2, 59, -9, 72, -18, 86, -14, 95), -- CABAC_ENTRY(323, 6, 70, 14, 60, 12, 70, 2, 95), -- CABAC_ENTRY(324, 10, 44, 16, 37, 5, 64, 0, 76), -- CABAC_ENTRY(325, 9, 31, 0, 47, -12, 70, -5, 74), -- CABAC_ENTRY(326, 12, 43, 18, 35, 11, 55, 0, 70), -- CABAC_ENTRY(327, 3, 53, 11, 37, 5, 56, -11, 75), -- CABAC_ENTRY(328, 14, 34, 12, 41, 0, 69, 1, 68), -- CABAC_ENTRY(329, 10, 38, 10, 41, 2, 65, 0, 65), -- CABAC_ENTRY(330, -3, 52, 2, 48, -6, 74, -14, 73), -- CABAC_ENTRY(331, 13, 40, 12, 41, 5, 54, 3, 62), -- CABAC_ENTRY(332, 17, 32, 13, 41, 7, 54, 4, 62), -- CABAC_ENTRY(333, 7, 44, 0, 59, -6, 76, -1, 68), -- CABAC_ENTRY(334, 7, 38, 3, 50, -11, 82, -13, 75), -- CABAC_ENTRY(335, 13, 50, 19, 40, -2, 77, 11, 55), -- CABAC_ENTRY(336, 10, 57, 3, 66, -2, 77, 5, 64), -- CABAC_ENTRY(337, 26, 43, 18, 50, 25, 42, 12, 70), -- -- /* Table 9-23 – Values of variables m and n for ctxIdx from 338 to 398 */ -- CABAC_ENTRY(338, 14, 11, 19, -6, 17, -13, 15, 6), -- CABAC_ENTRY(339, 11, 14, 18, -6, 16, -9, 6, 19), -- CABAC_ENTRY(340, 9, 11, 14, 0, 17, -12, 7, 16), -- CABAC_ENTRY(341, 18, 11, 26, -12, 27, -21, 12, 14), -- CABAC_ENTRY(342, 21, 9, 31, -16, 37, -30, 18, 13), -- CABAC_ENTRY(343, 23, -2, 33, -25, 41, -40, 13, 11), -- CABAC_ENTRY(344, 32, -15, 33, -22, 42, -41, 13, 15), -- CABAC_ENTRY(345, 32, -15, 37, -28, 48, -47, 15, 16), -- CABAC_ENTRY(346, 34, -21, 39, -30, 39, -32, 12, 23), -- CABAC_ENTRY(347, 39, -23, 42, -30, 46, -40, 13, 23), -- CABAC_ENTRY(348, 42, -33, 47, -42, 52, -51, 15, 20), -- CABAC_ENTRY(349, 41, -31, 45, -36, 46, -41, 14, 26), -- CABAC_ENTRY(350, 46, -28, 49, -34, 52, -39, 14, 44), -- CABAC_ENTRY(351, 38, -12, 41, -17, 43, -19, 17, 40), -- CABAC_ENTRY(352, 21, 29, 32, 9, 32, 11, 17, 47), -- CABAC_ENTRY(353, 45, -24, 69, -71, 61, -55, 24, 17), -- CABAC_ENTRY(354, 53, -45, 63, -63, 56, -46, 21, 21), -- CABAC_ENTRY(355, 48, -26, 66, -64, 62, -50, 25, 22), -- CABAC_ENTRY(356, 65, -43, 77, -74, 81, -67, 31, 27), -- CABAC_ENTRY(357, 43, -19, 54, -39, 45, -20, 22, 29), -- CABAC_ENTRY(358, 39, -10, 52, -35, 35, -2, 19, 35), -- CABAC_ENTRY(359, 30, 9, 41, -10, 28, 15, 14, 50), -- CABAC_ENTRY(360, 18, 26, 36, 0, 34, 1, 10, 57), -- CABAC_ENTRY(361, 20, 27, 40, -1, 39, 1, 7, 63), -- CABAC_ENTRY(362, 0, 57, 30, 14, 30, 17, -2, 77), -- CABAC_ENTRY(363, -14, 82, 28, 26, 20, 38, -4, 82), -- CABAC_ENTRY(364, -5, 75, 23, 37, 18, 45, -3, 94), -- CABAC_ENTRY(365, -19, 97, 12, 55, 15, 54, 9, 69), -- CABAC_ENTRY(366, -35, 125, 11, 65, 0, 79, -12, 109), -- CABAC_ENTRY(367, 27, 0, 37, -33, 36, -16, 36, -35), -- CABAC_ENTRY(368, 28, 0, 39, -36, 37, -14, 36, -34), -- CABAC_ENTRY(369, 31, -4, 40, -37, 37, -17, 32, -26), -- CABAC_ENTRY(370, 27, 6, 38, -30, 32, 1, 37, -30), -- CABAC_ENTRY(371, 34, 8, 46, -33, 34, 15, 44, -32), -- CABAC_ENTRY(372, 30, 10, 42, -30, 29, 15, 34, -18), -- CABAC_ENTRY(373, 24, 22, 40, -24, 24, 25, 34, -15), -- CABAC_ENTRY(374, 33, 19, 49, -29, 34, 22, 40, -15), -- CABAC_ENTRY(375, 22, 32, 38, -12, 31, 16, 33, -7), -- CABAC_ENTRY(376, 26, 31, 40, -10, 35, 18, 35, -5), -- CABAC_ENTRY(377, 21, 41, 38, -3, 31, 28, 33, 0), -- CABAC_ENTRY(378, 26, 44, 46, -5, 33, 41, 38, 2), -- CABAC_ENTRY(379, 23, 47, 31, 20, 36, 28, 33, 13), -- CABAC_ENTRY(380, 16, 65, 29, 30, 27, 47, 23, 35), -- CABAC_ENTRY(381, 14, 71, 25, 44, 21, 62, 13, 58), -- CABAC_ENTRY(382, 8, 60, 12, 48, 18, 31, 29, -3), -- CABAC_ENTRY(383, 6, 63, 11, 49, 19, 26, 26, 0), -- CABAC_ENTRY(384, 17, 65, 26, 45, 36, 24, 22, 30), -- CABAC_ENTRY(385, 21, 24, 22, 22, 24, 23, 31, -7), -- CABAC_ENTRY(386, 23, 20, 23, 22, 27, 16, 35, -15), -- CABAC_ENTRY(387, 26, 23, 27, 21, 24, 30, 34, -3), -- CABAC_ENTRY(388, 27, 32, 33, 20, 31, 29, 34, 3), -- CABAC_ENTRY(389, 28, 23, 26, 28, 22, 41, 36, -1), -- CABAC_ENTRY(390, 28, 24, 30, 24, 22, 42, 34, 5), -- CABAC_ENTRY(391, 23, 40, 27, 34, 16, 60, 32, 11), -- CABAC_ENTRY(392, 24, 32, 18, 42, 15, 52, 35, 5), -- CABAC_ENTRY(393, 28, 29, 25, 39, 14, 60, 34, 12), -- CABAC_ENTRY(394, 23, 42, 18, 50, 3, 78, 39, 11), -- CABAC_ENTRY(395, 19, 57, 12, 70, -16, 123, 30, 29), -- CABAC_ENTRY(396, 22, 53, 21, 54, 21, 53, 34, 26), -- CABAC_ENTRY(397, 22, 61, 14, 71, 22, 56, 29, 39), -- CABAC_ENTRY(398, 11, 86, 11, 83, 25, 61, 19, 66), -- -- /* Values of variables m and n for ctxIdx from 399 to 463 (not documented) */ -- CABAC_ENTRY(399, 12, 40, 25, 32, 21, 33, 31, 21), -- CABAC_ENTRY(400, 11, 51, 21, 49, 19, 50, 31, 31), -- CABAC_ENTRY(401, 14, 59, 21, 54, 17, 61, 25, 50), -- CABAC_ENTRY(402, -4, 79, -5, 85, -3, 78, -17, 120), -- CABAC_ENTRY(403, -7, 71, -6, 81, -8, 74, -20, 112), -- CABAC_ENTRY(404, -5, 69, -10, 77, -9, 72, -18, 114), -- CABAC_ENTRY(405, -9, 70, -7, 81, -10, 72, -11, 85), -- CABAC_ENTRY(406, -8, 66, -17, 80, -18, 75, -15, 92), -- CABAC_ENTRY(407, -10, 68, -18, 73, -12, 71, -14, 89), -- CABAC_ENTRY(408, -19, 73, -4, 74, -11, 63, -26, 71), -- CABAC_ENTRY(409, -12, 69, -10, 83, -5, 70, -15, 81), -- CABAC_ENTRY(410, -16, 70, -9, 71, -17, 75, -14, 80), -- CABAC_ENTRY(411, -15, 67, -9, 67, -14, 72, 0, 68), -- CABAC_ENTRY(412, -20, 62, -1, 61, -16, 67, -14, 70), -- CABAC_ENTRY(413, -19, 70, -8, 66, -8, 53, -24, 56), -- CABAC_ENTRY(414, -16, 66, -14, 66, -14, 59, -23, 68), -- CABAC_ENTRY(415, -22, 65, 0, 59, -9, 52, -24, 50), -- CABAC_ENTRY(416, -20, 63, 2, 59, -11, 68, -11, 74), -- CABAC_ENTRY(417, 9, -2, 17, -10, 9, -2, 23, -13), -- CABAC_ENTRY(418, 26, -9, 32, -13, 30, -10, 26, -13), -- CABAC_ENTRY(419, 33, -9, 42, -9, 31, -4, 40, -15), -- CABAC_ENTRY(420, 39, -7, 49, -5, 33, -1, 49, -14), -- CABAC_ENTRY(421, 41, -2, 53, 0, 33, 7, 44, 3), -- CABAC_ENTRY(422, 45, 3, 64, 3, 31, 12, 45, 6), -- CABAC_ENTRY(423, 49, 9, 68, 10, 37, 23, 44, 34), -- CABAC_ENTRY(424, 45, 27, 66, 27, 31, 38, 33, 54), -- CABAC_ENTRY(425, 36, 59, 47, 57, 20, 64, 19, 82), -- CABAC_ENTRY(426, -6, 66, -5, 71, -9, 71, -3, 75), -- CABAC_ENTRY(427, -7, 35, 0, 24, -7, 37, -1, 23), -- CABAC_ENTRY(428, -7, 42, -1, 36, -8, 44, 1, 34), -- CABAC_ENTRY(429, -8, 45, -2, 42, -11, 49, 1, 43), -- CABAC_ENTRY(430, -5, 48, -2, 52, -10, 56, 0, 54), -- CABAC_ENTRY(431, -12, 56, -9, 57, -12, 59, -2, 55), -- CABAC_ENTRY(432, -6, 60, -6, 63, -8, 63, 0, 61), -- CABAC_ENTRY(433, -5, 62, -4, 65, -9, 67, 1, 64), -- CABAC_ENTRY(434, -8, 66, -4, 67, -6, 68, 0, 68), -- CABAC_ENTRY(435, -8, 76, -7, 82, -10, 79, -9, 92), -- CABAC_ENTRY(436, -5, 85, -3, 81, -3, 78, -14, 106), -- CABAC_ENTRY(437, -6, 81, -3, 76, -8, 74, -13, 97), -- CABAC_ENTRY(438, -10, 77, -7, 72, -9, 72, -15, 90), -- CABAC_ENTRY(439, -7, 81, -6, 78, -10, 72, -12, 90), -- CABAC_ENTRY(440, -17, 80, -12, 72, -18, 75, -18, 88), -- CABAC_ENTRY(441, -18, 73, -14, 68, -12, 71, -10, 73), -- CABAC_ENTRY(442, -4, 74, -3, 70, -11, 63, -9, 79), -- CABAC_ENTRY(443, -10, 83, -6, 76, -5, 70, -14, 86), -- CABAC_ENTRY(444, -9, 71, -5, 66, -17, 75, -10, 73), -- CABAC_ENTRY(445, -9, 67, -5, 62, -14, 72, -10, 70), -- CABAC_ENTRY(446, -1, 61, 0, 57, -16, 67, -10, 69), -- CABAC_ENTRY(447, -8, 66, -4, 61, -8, 53, -5, 66), -- CABAC_ENTRY(448, -14, 66, -9, 60, -14, 59, -9, 64), -- CABAC_ENTRY(449, 0, 59, 1, 54, -9, 52, -5, 58), -- CABAC_ENTRY(450, 2, 59, 2, 58, -11, 68, 2, 59), -- CABAC_ENTRY(451, 21, -13, 17, -10, 9, -2, 21, -10), -- CABAC_ENTRY(452, 33, -14, 32, -13, 30, -10, 24, -11), -- CABAC_ENTRY(453, 39, -7, 42, -9, 31, -4, 28, -8), -- CABAC_ENTRY(454, 46, -2, 49, -5, 33, -1, 28, -1), -- CABAC_ENTRY(455, 51, 2, 53, 0, 33, 7, 29, 3), -- CABAC_ENTRY(456, 60, 6, 64, 3, 31, 12, 29, 9), -- CABAC_ENTRY(457, 61, 17, 68, 10, 37, 23, 35, 20), -- CABAC_ENTRY(458, 55, 34, 66, 27, 31, 38, 29, 36), -- CABAC_ENTRY(459, 42, 62, 47, 57, 20, 64, 14, 67), --}; -- - static void set_ps_field(u32 *buf, struct rkvdec_ps_field field, u32 value) - { - u8 bit = field.offset % 32, word = field.offset / 32; -diff --git a/include/media/v4l2-cabac/rkvdec-cabac.h b/include/media/v4l2-cabac/rkvdec-cabac.h -new file mode 100644 -index 000000000000..3324c4cb6130 ---- /dev/null -+++ b/include/media/v4l2-cabac/rkvdec-cabac.h -@@ -0,0 +1,509 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+ -+/* -+ * Define the H264 CABAC table common to rkvdec and rkvdec2 drivers. -+ */ -+ -+#ifndef RKVDEC_H264_CABAC_H_ -+#define RKVDEC_H264_CABAC_H_ -+ -+#define CABAC_ENTRY(ctxidx, idc0_m, idc0_n, idc1_m, idc1_n, \ -+ idc2_m, idc2_n, intra_m, intra_n) \ -+ [0][(ctxidx)] = {idc0_m, idc0_n}, \ -+ [1][(ctxidx)] = {idc1_m, idc1_n}, \ -+ [2][(ctxidx)] = {idc2_m, idc2_n}, \ -+ [3][(ctxidx)] = {intra_m, intra_n} -+ -+/* -+ * Constant CABAC table. -+ * Built from the tables described in section '9.3.1.1 Initialisation process -+ * for context variables' of the H264 spec. -+ */ -+static const s8 rkvdec_h264_cabac_table[4][464][2] = { -+ /* Table 9-12 – Values of variables m and n for ctxIdx from 0 to 10 */ -+ CABAC_ENTRY(0, 20, -15, 20, -15, 20, -15, 20, -15), -+ CABAC_ENTRY(1, 2, 54, 2, 54, 2, 54, 2, 54), -+ CABAC_ENTRY(2, 3, 74, 3, 74, 3, 74, 3, 74), -+ CABAC_ENTRY(3, 20, -15, 20, -15, 20, -15, 20, -15), -+ CABAC_ENTRY(4, 2, 54, 2, 54, 2, 54, 2, 54), -+ CABAC_ENTRY(5, 3, 74, 3, 74, 3, 74, 3, 74), -+ CABAC_ENTRY(6, -28, 127, -28, 127, -28, 127, -28, 127), -+ CABAC_ENTRY(7, -23, 104, -23, 104, -23, 104, -23, 104), -+ CABAC_ENTRY(8, -6, 53, -6, 53, -6, 53, -6, 53), -+ CABAC_ENTRY(9, -1, 54, -1, 54, -1, 54, -1, 54), -+ CABAC_ENTRY(10, 7, 51, 7, 51, 7, 51, 7, 51), -+ -+ /* Table 9-13 – Values of variables m and n for ctxIdx from 11 to 23 */ -+ CABAC_ENTRY(11, 23, 33, 22, 25, 29, 16, 0, 0), -+ CABAC_ENTRY(12, 23, 2, 34, 0, 25, 0, 0, 0), -+ CABAC_ENTRY(13, 21, 0, 16, 0, 14, 0, 0, 0), -+ CABAC_ENTRY(14, 1, 9, -2, 9, -10, 51, 0, 0), -+ CABAC_ENTRY(15, 0, 49, 4, 41, -3, 62, 0, 0), -+ CABAC_ENTRY(16, -37, 118, -29, 118, -27, 99, 0, 0), -+ CABAC_ENTRY(17, 5, 57, 2, 65, 26, 16, 0, 0), -+ CABAC_ENTRY(18, -13, 78, -6, 71, -4, 85, 0, 0), -+ CABAC_ENTRY(19, -11, 65, -13, 79, -24, 102, 0, 0), -+ CABAC_ENTRY(20, 1, 62, 5, 52, 5, 57, 0, 0), -+ CABAC_ENTRY(21, 12, 49, 9, 50, 6, 57, 0, 0), -+ CABAC_ENTRY(22, -4, 73, -3, 70, -17, 73, 0, 0), -+ CABAC_ENTRY(23, 17, 50, 10, 54, 14, 57, 0, 0), -+ -+ /* Table 9-14 – Values of variables m and n for ctxIdx from 24 to 39 */ -+ CABAC_ENTRY(24, 18, 64, 26, 34, 20, 40, 0, 0), -+ CABAC_ENTRY(25, 9, 43, 19, 22, 20, 10, 0, 0), -+ CABAC_ENTRY(26, 29, 0, 40, 0, 29, 0, 0, 0), -+ CABAC_ENTRY(27, 26, 67, 57, 2, 54, 0, 0, 0), -+ CABAC_ENTRY(28, 16, 90, 41, 36, 37, 42, 0, 0), -+ CABAC_ENTRY(29, 9, 104, 26, 69, 12, 97, 0, 0), -+ CABAC_ENTRY(30, -46, 127, -45, 127, -32, 127, 0, 0), -+ CABAC_ENTRY(31, -20, 104, -15, 101, -22, 117, 0, 0), -+ CABAC_ENTRY(32, 1, 67, -4, 76, -2, 74, 0, 0), -+ CABAC_ENTRY(33, -13, 78, -6, 71, -4, 85, 0, 0), -+ CABAC_ENTRY(34, -11, 65, -13, 79, -24, 102, 0, 0), -+ CABAC_ENTRY(35, 1, 62, 5, 52, 5, 57, 0, 0), -+ CABAC_ENTRY(36, -6, 86, 6, 69, -6, 93, 0, 0), -+ CABAC_ENTRY(37, -17, 95, -13, 90, -14, 88, 0, 0), -+ CABAC_ENTRY(38, -6, 61, 0, 52, -6, 44, 0, 0), -+ CABAC_ENTRY(39, 9, 45, 8, 43, 4, 55, 0, 0), -+ -+ /* Table 9-15 – Values of variables m and n for ctxIdx from 40 to 53 */ -+ CABAC_ENTRY(40, -3, 69, -2, 69, -11, 89, 0, 0), -+ CABAC_ENTRY(41, -6, 81, -5, 82, -15, 103, 0, 0), -+ CABAC_ENTRY(42, -11, 96, -10, 96, -21, 116, 0, 0), -+ CABAC_ENTRY(43, 6, 55, 2, 59, 19, 57, 0, 0), -+ CABAC_ENTRY(44, 7, 67, 2, 75, 20, 58, 0, 0), -+ CABAC_ENTRY(45, -5, 86, -3, 87, 4, 84, 0, 0), -+ CABAC_ENTRY(46, 2, 88, -3, 100, 6, 96, 0, 0), -+ CABAC_ENTRY(47, 0, 58, 1, 56, 1, 63, 0, 0), -+ CABAC_ENTRY(48, -3, 76, -3, 74, -5, 85, 0, 0), -+ CABAC_ENTRY(49, -10, 94, -6, 85, -13, 106, 0, 0), -+ CABAC_ENTRY(50, 5, 54, 0, 59, 5, 63, 0, 0), -+ CABAC_ENTRY(51, 4, 69, -3, 81, 6, 75, 0, 0), -+ CABAC_ENTRY(52, -3, 81, -7, 86, -3, 90, 0, 0), -+ CABAC_ENTRY(53, 0, 88, -5, 95, -1, 101, 0, 0), -+ -+ /* Table 9-16 – Values of variables m and n for ctxIdx from 54 to 59 */ -+ CABAC_ENTRY(54, -7, 67, -1, 66, 3, 55, 0, 0), -+ CABAC_ENTRY(55, -5, 74, -1, 77, -4, 79, 0, 0), -+ CABAC_ENTRY(56, -4, 74, 1, 70, -2, 75, 0, 0), -+ CABAC_ENTRY(57, -5, 80, -2, 86, -12, 97, 0, 0), -+ CABAC_ENTRY(58, -7, 72, -5, 72, -7, 50, 0, 0), -+ CABAC_ENTRY(59, 1, 58, 0, 61, 1, 60, 0, 0), -+ -+ /* Table 9-17 – Values of variables m and n for ctxIdx from 60 to 69 */ -+ CABAC_ENTRY(60, 0, 41, 0, 41, 0, 41, 0, 41), -+ CABAC_ENTRY(61, 0, 63, 0, 63, 0, 63, 0, 63), -+ CABAC_ENTRY(62, 0, 63, 0, 63, 0, 63, 0, 63), -+ CABAC_ENTRY(63, 0, 63, 0, 63, 0, 63, 0, 63), -+ CABAC_ENTRY(64, -9, 83, -9, 83, -9, 83, -9, 83), -+ CABAC_ENTRY(65, 4, 86, 4, 86, 4, 86, 4, 86), -+ CABAC_ENTRY(66, 0, 97, 0, 97, 0, 97, 0, 97), -+ CABAC_ENTRY(67, -7, 72, -7, 72, -7, 72, -7, 72), -+ CABAC_ENTRY(68, 13, 41, 13, 41, 13, 41, 13, 41), -+ CABAC_ENTRY(69, 3, 62, 3, 62, 3, 62, 3, 62), -+ -+ /* Table 9-18 – Values of variables m and n for ctxIdx from 70 to 104 */ -+ CABAC_ENTRY(70, 0, 45, 13, 15, 7, 34, 0, 11), -+ CABAC_ENTRY(71, -4, 78, 7, 51, -9, 88, 1, 55), -+ CABAC_ENTRY(72, -3, 96, 2, 80, -20, 127, 0, 69), -+ CABAC_ENTRY(73, -27, 126, -39, 127, -36, 127, -17, 127), -+ CABAC_ENTRY(74, -28, 98, -18, 91, -17, 91, -13, 102), -+ CABAC_ENTRY(75, -25, 101, -17, 96, -14, 95, 0, 82), -+ CABAC_ENTRY(76, -23, 67, -26, 81, -25, 84, -7, 74), -+ CABAC_ENTRY(77, -28, 82, -35, 98, -25, 86, -21, 107), -+ CABAC_ENTRY(78, -20, 94, -24, 102, -12, 89, -27, 127), -+ CABAC_ENTRY(79, -16, 83, -23, 97, -17, 91, -31, 127), -+ CABAC_ENTRY(80, -22, 110, -27, 119, -31, 127, -24, 127), -+ CABAC_ENTRY(81, -21, 91, -24, 99, -14, 76, -18, 95), -+ CABAC_ENTRY(82, -18, 102, -21, 110, -18, 103, -27, 127), -+ CABAC_ENTRY(83, -13, 93, -18, 102, -13, 90, -21, 114), -+ CABAC_ENTRY(84, -29, 127, -36, 127, -37, 127, -30, 127), -+ CABAC_ENTRY(85, -7, 92, 0, 80, 11, 80, -17, 123), -+ CABAC_ENTRY(86, -5, 89, -5, 89, 5, 76, -12, 115), -+ CABAC_ENTRY(87, -7, 96, -7, 94, 2, 84, -16, 122), -+ CABAC_ENTRY(88, -13, 108, -4, 92, 5, 78, -11, 115), -+ CABAC_ENTRY(89, -3, 46, 0, 39, -6, 55, -12, 63), -+ CABAC_ENTRY(90, -1, 65, 0, 65, 4, 61, -2, 68), -+ CABAC_ENTRY(91, -1, 57, -15, 84, -14, 83, -15, 84), -+ CABAC_ENTRY(92, -9, 93, -35, 127, -37, 127, -13, 104), -+ CABAC_ENTRY(93, -3, 74, -2, 73, -5, 79, -3, 70), -+ CABAC_ENTRY(94, -9, 92, -12, 104, -11, 104, -8, 93), -+ CABAC_ENTRY(95, -8, 87, -9, 91, -11, 91, -10, 90), -+ CABAC_ENTRY(96, -23, 126, -31, 127, -30, 127, -30, 127), -+ CABAC_ENTRY(97, 5, 54, 3, 55, 0, 65, -1, 74), -+ CABAC_ENTRY(98, 6, 60, 7, 56, -2, 79, -6, 97), -+ CABAC_ENTRY(99, 6, 59, 7, 55, 0, 72, -7, 91), -+ CABAC_ENTRY(100, 6, 69, 8, 61, -4, 92, -20, 127), -+ CABAC_ENTRY(101, -1, 48, -3, 53, -6, 56, -4, 56), -+ CABAC_ENTRY(102, 0, 68, 0, 68, 3, 68, -5, 82), -+ CABAC_ENTRY(103, -4, 69, -7, 74, -8, 71, -7, 76), -+ CABAC_ENTRY(104, -8, 88, -9, 88, -13, 98, -22, 125), -+ -+ /* Table 9-19 – Values of variables m and n for ctxIdx from 105 to 165 */ -+ CABAC_ENTRY(105, -2, 85, -13, 103, -4, 86, -7, 93), -+ CABAC_ENTRY(106, -6, 78, -13, 91, -12, 88, -11, 87), -+ CABAC_ENTRY(107, -1, 75, -9, 89, -5, 82, -3, 77), -+ CABAC_ENTRY(108, -7, 77, -14, 92, -3, 72, -5, 71), -+ CABAC_ENTRY(109, 2, 54, -8, 76, -4, 67, -4, 63), -+ CABAC_ENTRY(110, 5, 50, -12, 87, -8, 72, -4, 68), -+ CABAC_ENTRY(111, -3, 68, -23, 110, -16, 89, -12, 84), -+ CABAC_ENTRY(112, 1, 50, -24, 105, -9, 69, -7, 62), -+ CABAC_ENTRY(113, 6, 42, -10, 78, -1, 59, -7, 65), -+ CABAC_ENTRY(114, -4, 81, -20, 112, 5, 66, 8, 61), -+ CABAC_ENTRY(115, 1, 63, -17, 99, 4, 57, 5, 56), -+ CABAC_ENTRY(116, -4, 70, -78, 127, -4, 71, -2, 66), -+ CABAC_ENTRY(117, 0, 67, -70, 127, -2, 71, 1, 64), -+ CABAC_ENTRY(118, 2, 57, -50, 127, 2, 58, 0, 61), -+ CABAC_ENTRY(119, -2, 76, -46, 127, -1, 74, -2, 78), -+ CABAC_ENTRY(120, 11, 35, -4, 66, -4, 44, 1, 50), -+ CABAC_ENTRY(121, 4, 64, -5, 78, -1, 69, 7, 52), -+ CABAC_ENTRY(122, 1, 61, -4, 71, 0, 62, 10, 35), -+ CABAC_ENTRY(123, 11, 35, -8, 72, -7, 51, 0, 44), -+ CABAC_ENTRY(124, 18, 25, 2, 59, -4, 47, 11, 38), -+ CABAC_ENTRY(125, 12, 24, -1, 55, -6, 42, 1, 45), -+ CABAC_ENTRY(126, 13, 29, -7, 70, -3, 41, 0, 46), -+ CABAC_ENTRY(127, 13, 36, -6, 75, -6, 53, 5, 44), -+ CABAC_ENTRY(128, -10, 93, -8, 89, 8, 76, 31, 17), -+ CABAC_ENTRY(129, -7, 73, -34, 119, -9, 78, 1, 51), -+ CABAC_ENTRY(130, -2, 73, -3, 75, -11, 83, 7, 50), -+ CABAC_ENTRY(131, 13, 46, 32, 20, 9, 52, 28, 19), -+ CABAC_ENTRY(132, 9, 49, 30, 22, 0, 67, 16, 33), -+ CABAC_ENTRY(133, -7, 100, -44, 127, -5, 90, 14, 62), -+ CABAC_ENTRY(134, 9, 53, 0, 54, 1, 67, -13, 108), -+ CABAC_ENTRY(135, 2, 53, -5, 61, -15, 72, -15, 100), -+ CABAC_ENTRY(136, 5, 53, 0, 58, -5, 75, -13, 101), -+ CABAC_ENTRY(137, -2, 61, -1, 60, -8, 80, -13, 91), -+ CABAC_ENTRY(138, 0, 56, -3, 61, -21, 83, -12, 94), -+ CABAC_ENTRY(139, 0, 56, -8, 67, -21, 64, -10, 88), -+ CABAC_ENTRY(140, -13, 63, -25, 84, -13, 31, -16, 84), -+ CABAC_ENTRY(141, -5, 60, -14, 74, -25, 64, -10, 86), -+ CABAC_ENTRY(142, -1, 62, -5, 65, -29, 94, -7, 83), -+ CABAC_ENTRY(143, 4, 57, 5, 52, 9, 75, -13, 87), -+ CABAC_ENTRY(144, -6, 69, 2, 57, 17, 63, -19, 94), -+ CABAC_ENTRY(145, 4, 57, 0, 61, -8, 74, 1, 70), -+ CABAC_ENTRY(146, 14, 39, -9, 69, -5, 35, 0, 72), -+ CABAC_ENTRY(147, 4, 51, -11, 70, -2, 27, -5, 74), -+ CABAC_ENTRY(148, 13, 68, 18, 55, 13, 91, 18, 59), -+ CABAC_ENTRY(149, 3, 64, -4, 71, 3, 65, -8, 102), -+ CABAC_ENTRY(150, 1, 61, 0, 58, -7, 69, -15, 100), -+ CABAC_ENTRY(151, 9, 63, 7, 61, 8, 77, 0, 95), -+ CABAC_ENTRY(152, 7, 50, 9, 41, -10, 66, -4, 75), -+ CABAC_ENTRY(153, 16, 39, 18, 25, 3, 62, 2, 72), -+ CABAC_ENTRY(154, 5, 44, 9, 32, -3, 68, -11, 75), -+ CABAC_ENTRY(155, 4, 52, 5, 43, -20, 81, -3, 71), -+ CABAC_ENTRY(156, 11, 48, 9, 47, 0, 30, 15, 46), -+ CABAC_ENTRY(157, -5, 60, 0, 44, 1, 7, -13, 69), -+ CABAC_ENTRY(158, -1, 59, 0, 51, -3, 23, 0, 62), -+ CABAC_ENTRY(159, 0, 59, 2, 46, -21, 74, 0, 65), -+ CABAC_ENTRY(160, 22, 33, 19, 38, 16, 66, 21, 37), -+ CABAC_ENTRY(161, 5, 44, -4, 66, -23, 124, -15, 72), -+ CABAC_ENTRY(162, 14, 43, 15, 38, 17, 37, 9, 57), -+ CABAC_ENTRY(163, -1, 78, 12, 42, 44, -18, 16, 54), -+ CABAC_ENTRY(164, 0, 60, 9, 34, 50, -34, 0, 62), -+ CABAC_ENTRY(165, 9, 69, 0, 89, -22, 127, 12, 72), -+ -+ /* Table 9-20 – Values of variables m and n for ctxIdx from 166 to 226 */ -+ CABAC_ENTRY(166, 11, 28, 4, 45, 4, 39, 24, 0), -+ CABAC_ENTRY(167, 2, 40, 10, 28, 0, 42, 15, 9), -+ CABAC_ENTRY(168, 3, 44, 10, 31, 7, 34, 8, 25), -+ CABAC_ENTRY(169, 0, 49, 33, -11, 11, 29, 13, 18), -+ CABAC_ENTRY(170, 0, 46, 52, -43, 8, 31, 15, 9), -+ CABAC_ENTRY(171, 2, 44, 18, 15, 6, 37, 13, 19), -+ CABAC_ENTRY(172, 2, 51, 28, 0, 7, 42, 10, 37), -+ CABAC_ENTRY(173, 0, 47, 35, -22, 3, 40, 12, 18), -+ CABAC_ENTRY(174, 4, 39, 38, -25, 8, 33, 6, 29), -+ CABAC_ENTRY(175, 2, 62, 34, 0, 13, 43, 20, 33), -+ CABAC_ENTRY(176, 6, 46, 39, -18, 13, 36, 15, 30), -+ CABAC_ENTRY(177, 0, 54, 32, -12, 4, 47, 4, 45), -+ CABAC_ENTRY(178, 3, 54, 102, -94, 3, 55, 1, 58), -+ CABAC_ENTRY(179, 2, 58, 0, 0, 2, 58, 0, 62), -+ CABAC_ENTRY(180, 4, 63, 56, -15, 6, 60, 7, 61), -+ CABAC_ENTRY(181, 6, 51, 33, -4, 8, 44, 12, 38), -+ CABAC_ENTRY(182, 6, 57, 29, 10, 11, 44, 11, 45), -+ CABAC_ENTRY(183, 7, 53, 37, -5, 14, 42, 15, 39), -+ CABAC_ENTRY(184, 6, 52, 51, -29, 7, 48, 11, 42), -+ CABAC_ENTRY(185, 6, 55, 39, -9, 4, 56, 13, 44), -+ CABAC_ENTRY(186, 11, 45, 52, -34, 4, 52, 16, 45), -+ CABAC_ENTRY(187, 14, 36, 69, -58, 13, 37, 12, 41), -+ CABAC_ENTRY(188, 8, 53, 67, -63, 9, 49, 10, 49), -+ CABAC_ENTRY(189, -1, 82, 44, -5, 19, 58, 30, 34), -+ CABAC_ENTRY(190, 7, 55, 32, 7, 10, 48, 18, 42), -+ CABAC_ENTRY(191, -3, 78, 55, -29, 12, 45, 10, 55), -+ CABAC_ENTRY(192, 15, 46, 32, 1, 0, 69, 17, 51), -+ CABAC_ENTRY(193, 22, 31, 0, 0, 20, 33, 17, 46), -+ CABAC_ENTRY(194, -1, 84, 27, 36, 8, 63, 0, 89), -+ CABAC_ENTRY(195, 25, 7, 33, -25, 35, -18, 26, -19), -+ CABAC_ENTRY(196, 30, -7, 34, -30, 33, -25, 22, -17), -+ CABAC_ENTRY(197, 28, 3, 36, -28, 28, -3, 26, -17), -+ CABAC_ENTRY(198, 28, 4, 38, -28, 24, 10, 30, -25), -+ CABAC_ENTRY(199, 32, 0, 38, -27, 27, 0, 28, -20), -+ CABAC_ENTRY(200, 34, -1, 34, -18, 34, -14, 33, -23), -+ CABAC_ENTRY(201, 30, 6, 35, -16, 52, -44, 37, -27), -+ CABAC_ENTRY(202, 30, 6, 34, -14, 39, -24, 33, -23), -+ CABAC_ENTRY(203, 32, 9, 32, -8, 19, 17, 40, -28), -+ CABAC_ENTRY(204, 31, 19, 37, -6, 31, 25, 38, -17), -+ CABAC_ENTRY(205, 26, 27, 35, 0, 36, 29, 33, -11), -+ CABAC_ENTRY(206, 26, 30, 30, 10, 24, 33, 40, -15), -+ CABAC_ENTRY(207, 37, 20, 28, 18, 34, 15, 41, -6), -+ CABAC_ENTRY(208, 28, 34, 26, 25, 30, 20, 38, 1), -+ CABAC_ENTRY(209, 17, 70, 29, 41, 22, 73, 41, 17), -+ CABAC_ENTRY(210, 1, 67, 0, 75, 20, 34, 30, -6), -+ CABAC_ENTRY(211, 5, 59, 2, 72, 19, 31, 27, 3), -+ CABAC_ENTRY(212, 9, 67, 8, 77, 27, 44, 26, 22), -+ CABAC_ENTRY(213, 16, 30, 14, 35, 19, 16, 37, -16), -+ CABAC_ENTRY(214, 18, 32, 18, 31, 15, 36, 35, -4), -+ CABAC_ENTRY(215, 18, 35, 17, 35, 15, 36, 38, -8), -+ CABAC_ENTRY(216, 22, 29, 21, 30, 21, 28, 38, -3), -+ CABAC_ENTRY(217, 24, 31, 17, 45, 25, 21, 37, 3), -+ CABAC_ENTRY(218, 23, 38, 20, 42, 30, 20, 38, 5), -+ CABAC_ENTRY(219, 18, 43, 18, 45, 31, 12, 42, 0), -+ CABAC_ENTRY(220, 20, 41, 27, 26, 27, 16, 35, 16), -+ CABAC_ENTRY(221, 11, 63, 16, 54, 24, 42, 39, 22), -+ CABAC_ENTRY(222, 9, 59, 7, 66, 0, 93, 14, 48), -+ CABAC_ENTRY(223, 9, 64, 16, 56, 14, 56, 27, 37), -+ CABAC_ENTRY(224, -1, 94, 11, 73, 15, 57, 21, 60), -+ CABAC_ENTRY(225, -2, 89, 10, 67, 26, 38, 12, 68), -+ CABAC_ENTRY(226, -9, 108, -10, 116, -24, 127, 2, 97), -+ -+ /* Table 9-21 – Values of variables m and n for ctxIdx from 227 to 275 */ -+ CABAC_ENTRY(227, -6, 76, -23, 112, -24, 115, -3, 71), -+ CABAC_ENTRY(228, -2, 44, -15, 71, -22, 82, -6, 42), -+ CABAC_ENTRY(229, 0, 45, -7, 61, -9, 62, -5, 50), -+ CABAC_ENTRY(230, 0, 52, 0, 53, 0, 53, -3, 54), -+ CABAC_ENTRY(231, -3, 64, -5, 66, 0, 59, -2, 62), -+ CABAC_ENTRY(232, -2, 59, -11, 77, -14, 85, 0, 58), -+ CABAC_ENTRY(233, -4, 70, -9, 80, -13, 89, 1, 63), -+ CABAC_ENTRY(234, -4, 75, -9, 84, -13, 94, -2, 72), -+ CABAC_ENTRY(235, -8, 82, -10, 87, -11, 92, -1, 74), -+ CABAC_ENTRY(236, -17, 102, -34, 127, -29, 127, -9, 91), -+ CABAC_ENTRY(237, -9, 77, -21, 101, -21, 100, -5, 67), -+ CABAC_ENTRY(238, 3, 24, -3, 39, -14, 57, -5, 27), -+ CABAC_ENTRY(239, 0, 42, -5, 53, -12, 67, -3, 39), -+ CABAC_ENTRY(240, 0, 48, -7, 61, -11, 71, -2, 44), -+ CABAC_ENTRY(241, 0, 55, -11, 75, -10, 77, 0, 46), -+ CABAC_ENTRY(242, -6, 59, -15, 77, -21, 85, -16, 64), -+ CABAC_ENTRY(243, -7, 71, -17, 91, -16, 88, -8, 68), -+ CABAC_ENTRY(244, -12, 83, -25, 107, -23, 104, -10, 78), -+ CABAC_ENTRY(245, -11, 87, -25, 111, -15, 98, -6, 77), -+ CABAC_ENTRY(246, -30, 119, -28, 122, -37, 127, -10, 86), -+ CABAC_ENTRY(247, 1, 58, -11, 76, -10, 82, -12, 92), -+ CABAC_ENTRY(248, -3, 29, -10, 44, -8, 48, -15, 55), -+ CABAC_ENTRY(249, -1, 36, -10, 52, -8, 61, -10, 60), -+ CABAC_ENTRY(250, 1, 38, -10, 57, -8, 66, -6, 62), -+ CABAC_ENTRY(251, 2, 43, -9, 58, -7, 70, -4, 65), -+ CABAC_ENTRY(252, -6, 55, -16, 72, -14, 75, -12, 73), -+ CABAC_ENTRY(253, 0, 58, -7, 69, -10, 79, -8, 76), -+ CABAC_ENTRY(254, 0, 64, -4, 69, -9, 83, -7, 80), -+ CABAC_ENTRY(255, -3, 74, -5, 74, -12, 92, -9, 88), -+ CABAC_ENTRY(256, -10, 90, -9, 86, -18, 108, -17, 110), -+ CABAC_ENTRY(257, 0, 70, 2, 66, -4, 79, -11, 97), -+ CABAC_ENTRY(258, -4, 29, -9, 34, -22, 69, -20, 84), -+ CABAC_ENTRY(259, 5, 31, 1, 32, -16, 75, -11, 79), -+ CABAC_ENTRY(260, 7, 42, 11, 31, -2, 58, -6, 73), -+ CABAC_ENTRY(261, 1, 59, 5, 52, 1, 58, -4, 74), -+ CABAC_ENTRY(262, -2, 58, -2, 55, -13, 78, -13, 86), -+ CABAC_ENTRY(263, -3, 72, -2, 67, -9, 83, -13, 96), -+ CABAC_ENTRY(264, -3, 81, 0, 73, -4, 81, -11, 97), -+ CABAC_ENTRY(265, -11, 97, -8, 89, -13, 99, -19, 117), -+ CABAC_ENTRY(266, 0, 58, 3, 52, -13, 81, -8, 78), -+ CABAC_ENTRY(267, 8, 5, 7, 4, -6, 38, -5, 33), -+ CABAC_ENTRY(268, 10, 14, 10, 8, -13, 62, -4, 48), -+ CABAC_ENTRY(269, 14, 18, 17, 8, -6, 58, -2, 53), -+ CABAC_ENTRY(270, 13, 27, 16, 19, -2, 59, -3, 62), -+ CABAC_ENTRY(271, 2, 40, 3, 37, -16, 73, -13, 71), -+ CABAC_ENTRY(272, 0, 58, -1, 61, -10, 76, -10, 79), -+ CABAC_ENTRY(273, -3, 70, -5, 73, -13, 86, -12, 86), -+ CABAC_ENTRY(274, -6, 79, -1, 70, -9, 83, -13, 90), -+ CABAC_ENTRY(275, -8, 85, -4, 78, -10, 87, -14, 97), -+ -+ /* Table 9-22 – Values of variables m and n for ctxIdx from 277 to 337 */ -+ CABAC_ENTRY(277, -13, 106, -21, 126, -22, 127, -6, 93), -+ CABAC_ENTRY(278, -16, 106, -23, 124, -25, 127, -6, 84), -+ CABAC_ENTRY(279, -10, 87, -20, 110, -25, 120, -8, 79), -+ CABAC_ENTRY(280, -21, 114, -26, 126, -27, 127, 0, 66), -+ CABAC_ENTRY(281, -18, 110, -25, 124, -19, 114, -1, 71), -+ CABAC_ENTRY(282, -14, 98, -17, 105, -23, 117, 0, 62), -+ CABAC_ENTRY(283, -22, 110, -27, 121, -25, 118, -2, 60), -+ CABAC_ENTRY(284, -21, 106, -27, 117, -26, 117, -2, 59), -+ CABAC_ENTRY(285, -18, 103, -17, 102, -24, 113, -5, 75), -+ CABAC_ENTRY(286, -21, 107, -26, 117, -28, 118, -3, 62), -+ CABAC_ENTRY(287, -23, 108, -27, 116, -31, 120, -4, 58), -+ CABAC_ENTRY(288, -26, 112, -33, 122, -37, 124, -9, 66), -+ CABAC_ENTRY(289, -10, 96, -10, 95, -10, 94, -1, 79), -+ CABAC_ENTRY(290, -12, 95, -14, 100, -15, 102, 0, 71), -+ CABAC_ENTRY(291, -5, 91, -8, 95, -10, 99, 3, 68), -+ CABAC_ENTRY(292, -9, 93, -17, 111, -13, 106, 10, 44), -+ CABAC_ENTRY(293, -22, 94, -28, 114, -50, 127, -7, 62), -+ CABAC_ENTRY(294, -5, 86, -6, 89, -5, 92, 15, 36), -+ CABAC_ENTRY(295, 9, 67, -2, 80, 17, 57, 14, 40), -+ CABAC_ENTRY(296, -4, 80, -4, 82, -5, 86, 16, 27), -+ CABAC_ENTRY(297, -10, 85, -9, 85, -13, 94, 12, 29), -+ CABAC_ENTRY(298, -1, 70, -8, 81, -12, 91, 1, 44), -+ CABAC_ENTRY(299, 7, 60, -1, 72, -2, 77, 20, 36), -+ CABAC_ENTRY(300, 9, 58, 5, 64, 0, 71, 18, 32), -+ CABAC_ENTRY(301, 5, 61, 1, 67, -1, 73, 5, 42), -+ CABAC_ENTRY(302, 12, 50, 9, 56, 4, 64, 1, 48), -+ CABAC_ENTRY(303, 15, 50, 0, 69, -7, 81, 10, 62), -+ CABAC_ENTRY(304, 18, 49, 1, 69, 5, 64, 17, 46), -+ CABAC_ENTRY(305, 17, 54, 7, 69, 15, 57, 9, 64), -+ CABAC_ENTRY(306, 10, 41, -7, 69, 1, 67, -12, 104), -+ CABAC_ENTRY(307, 7, 46, -6, 67, 0, 68, -11, 97), -+ CABAC_ENTRY(308, -1, 51, -16, 77, -10, 67, -16, 96), -+ CABAC_ENTRY(309, 7, 49, -2, 64, 1, 68, -7, 88), -+ CABAC_ENTRY(310, 8, 52, 2, 61, 0, 77, -8, 85), -+ CABAC_ENTRY(311, 9, 41, -6, 67, 2, 64, -7, 85), -+ CABAC_ENTRY(312, 6, 47, -3, 64, 0, 68, -9, 85), -+ CABAC_ENTRY(313, 2, 55, 2, 57, -5, 78, -13, 88), -+ CABAC_ENTRY(314, 13, 41, -3, 65, 7, 55, 4, 66), -+ CABAC_ENTRY(315, 10, 44, -3, 66, 5, 59, -3, 77), -+ CABAC_ENTRY(316, 6, 50, 0, 62, 2, 65, -3, 76), -+ CABAC_ENTRY(317, 5, 53, 9, 51, 14, 54, -6, 76), -+ CABAC_ENTRY(318, 13, 49, -1, 66, 15, 44, 10, 58), -+ CABAC_ENTRY(319, 4, 63, -2, 71, 5, 60, -1, 76), -+ CABAC_ENTRY(320, 6, 64, -2, 75, 2, 70, -1, 83), -+ CABAC_ENTRY(321, -2, 69, -1, 70, -2, 76, -7, 99), -+ CABAC_ENTRY(322, -2, 59, -9, 72, -18, 86, -14, 95), -+ CABAC_ENTRY(323, 6, 70, 14, 60, 12, 70, 2, 95), -+ CABAC_ENTRY(324, 10, 44, 16, 37, 5, 64, 0, 76), -+ CABAC_ENTRY(325, 9, 31, 0, 47, -12, 70, -5, 74), -+ CABAC_ENTRY(326, 12, 43, 18, 35, 11, 55, 0, 70), -+ CABAC_ENTRY(327, 3, 53, 11, 37, 5, 56, -11, 75), -+ CABAC_ENTRY(328, 14, 34, 12, 41, 0, 69, 1, 68), -+ CABAC_ENTRY(329, 10, 38, 10, 41, 2, 65, 0, 65), -+ CABAC_ENTRY(330, -3, 52, 2, 48, -6, 74, -14, 73), -+ CABAC_ENTRY(331, 13, 40, 12, 41, 5, 54, 3, 62), -+ CABAC_ENTRY(332, 17, 32, 13, 41, 7, 54, 4, 62), -+ CABAC_ENTRY(333, 7, 44, 0, 59, -6, 76, -1, 68), -+ CABAC_ENTRY(334, 7, 38, 3, 50, -11, 82, -13, 75), -+ CABAC_ENTRY(335, 13, 50, 19, 40, -2, 77, 11, 55), -+ CABAC_ENTRY(336, 10, 57, 3, 66, -2, 77, 5, 64), -+ CABAC_ENTRY(337, 26, 43, 18, 50, 25, 42, 12, 70), -+ -+ /* Table 9-23 – Values of variables m and n for ctxIdx from 338 to 398 */ -+ CABAC_ENTRY(338, 14, 11, 19, -6, 17, -13, 15, 6), -+ CABAC_ENTRY(339, 11, 14, 18, -6, 16, -9, 6, 19), -+ CABAC_ENTRY(340, 9, 11, 14, 0, 17, -12, 7, 16), -+ CABAC_ENTRY(341, 18, 11, 26, -12, 27, -21, 12, 14), -+ CABAC_ENTRY(342, 21, 9, 31, -16, 37, -30, 18, 13), -+ CABAC_ENTRY(343, 23, -2, 33, -25, 41, -40, 13, 11), -+ CABAC_ENTRY(344, 32, -15, 33, -22, 42, -41, 13, 15), -+ CABAC_ENTRY(345, 32, -15, 37, -28, 48, -47, 15, 16), -+ CABAC_ENTRY(346, 34, -21, 39, -30, 39, -32, 12, 23), -+ CABAC_ENTRY(347, 39, -23, 42, -30, 46, -40, 13, 23), -+ CABAC_ENTRY(348, 42, -33, 47, -42, 52, -51, 15, 20), -+ CABAC_ENTRY(349, 41, -31, 45, -36, 46, -41, 14, 26), -+ CABAC_ENTRY(350, 46, -28, 49, -34, 52, -39, 14, 44), -+ CABAC_ENTRY(351, 38, -12, 41, -17, 43, -19, 17, 40), -+ CABAC_ENTRY(352, 21, 29, 32, 9, 32, 11, 17, 47), -+ CABAC_ENTRY(353, 45, -24, 69, -71, 61, -55, 24, 17), -+ CABAC_ENTRY(354, 53, -45, 63, -63, 56, -46, 21, 21), -+ CABAC_ENTRY(355, 48, -26, 66, -64, 62, -50, 25, 22), -+ CABAC_ENTRY(356, 65, -43, 77, -74, 81, -67, 31, 27), -+ CABAC_ENTRY(357, 43, -19, 54, -39, 45, -20, 22, 29), -+ CABAC_ENTRY(358, 39, -10, 52, -35, 35, -2, 19, 35), -+ CABAC_ENTRY(359, 30, 9, 41, -10, 28, 15, 14, 50), -+ CABAC_ENTRY(360, 18, 26, 36, 0, 34, 1, 10, 57), -+ CABAC_ENTRY(361, 20, 27, 40, -1, 39, 1, 7, 63), -+ CABAC_ENTRY(362, 0, 57, 30, 14, 30, 17, -2, 77), -+ CABAC_ENTRY(363, -14, 82, 28, 26, 20, 38, -4, 82), -+ CABAC_ENTRY(364, -5, 75, 23, 37, 18, 45, -3, 94), -+ CABAC_ENTRY(365, -19, 97, 12, 55, 15, 54, 9, 69), -+ CABAC_ENTRY(366, -35, 125, 11, 65, 0, 79, -12, 109), -+ CABAC_ENTRY(367, 27, 0, 37, -33, 36, -16, 36, -35), -+ CABAC_ENTRY(368, 28, 0, 39, -36, 37, -14, 36, -34), -+ CABAC_ENTRY(369, 31, -4, 40, -37, 37, -17, 32, -26), -+ CABAC_ENTRY(370, 27, 6, 38, -30, 32, 1, 37, -30), -+ CABAC_ENTRY(371, 34, 8, 46, -33, 34, 15, 44, -32), -+ CABAC_ENTRY(372, 30, 10, 42, -30, 29, 15, 34, -18), -+ CABAC_ENTRY(373, 24, 22, 40, -24, 24, 25, 34, -15), -+ CABAC_ENTRY(374, 33, 19, 49, -29, 34, 22, 40, -15), -+ CABAC_ENTRY(375, 22, 32, 38, -12, 31, 16, 33, -7), -+ CABAC_ENTRY(376, 26, 31, 40, -10, 35, 18, 35, -5), -+ CABAC_ENTRY(377, 21, 41, 38, -3, 31, 28, 33, 0), -+ CABAC_ENTRY(378, 26, 44, 46, -5, 33, 41, 38, 2), -+ CABAC_ENTRY(379, 23, 47, 31, 20, 36, 28, 33, 13), -+ CABAC_ENTRY(380, 16, 65, 29, 30, 27, 47, 23, 35), -+ CABAC_ENTRY(381, 14, 71, 25, 44, 21, 62, 13, 58), -+ CABAC_ENTRY(382, 8, 60, 12, 48, 18, 31, 29, -3), -+ CABAC_ENTRY(383, 6, 63, 11, 49, 19, 26, 26, 0), -+ CABAC_ENTRY(384, 17, 65, 26, 45, 36, 24, 22, 30), -+ CABAC_ENTRY(385, 21, 24, 22, 22, 24, 23, 31, -7), -+ CABAC_ENTRY(386, 23, 20, 23, 22, 27, 16, 35, -15), -+ CABAC_ENTRY(387, 26, 23, 27, 21, 24, 30, 34, -3), -+ CABAC_ENTRY(388, 27, 32, 33, 20, 31, 29, 34, 3), -+ CABAC_ENTRY(389, 28, 23, 26, 28, 22, 41, 36, -1), -+ CABAC_ENTRY(390, 28, 24, 30, 24, 22, 42, 34, 5), -+ CABAC_ENTRY(391, 23, 40, 27, 34, 16, 60, 32, 11), -+ CABAC_ENTRY(392, 24, 32, 18, 42, 15, 52, 35, 5), -+ CABAC_ENTRY(393, 28, 29, 25, 39, 14, 60, 34, 12), -+ CABAC_ENTRY(394, 23, 42, 18, 50, 3, 78, 39, 11), -+ CABAC_ENTRY(395, 19, 57, 12, 70, -16, 123, 30, 29), -+ CABAC_ENTRY(396, 22, 53, 21, 54, 21, 53, 34, 26), -+ CABAC_ENTRY(397, 22, 61, 14, 71, 22, 56, 29, 39), -+ CABAC_ENTRY(398, 11, 86, 11, 83, 25, 61, 19, 66), -+ -+ /* Values of variables m and n for ctxIdx from 399 to 463 (not documented) */ -+ CABAC_ENTRY(399, 12, 40, 25, 32, 21, 33, 31, 21), -+ CABAC_ENTRY(400, 11, 51, 21, 49, 19, 50, 31, 31), -+ CABAC_ENTRY(401, 14, 59, 21, 54, 17, 61, 25, 50), -+ CABAC_ENTRY(402, -4, 79, -5, 85, -3, 78, -17, 120), -+ CABAC_ENTRY(403, -7, 71, -6, 81, -8, 74, -20, 112), -+ CABAC_ENTRY(404, -5, 69, -10, 77, -9, 72, -18, 114), -+ CABAC_ENTRY(405, -9, 70, -7, 81, -10, 72, -11, 85), -+ CABAC_ENTRY(406, -8, 66, -17, 80, -18, 75, -15, 92), -+ CABAC_ENTRY(407, -10, 68, -18, 73, -12, 71, -14, 89), -+ CABAC_ENTRY(408, -19, 73, -4, 74, -11, 63, -26, 71), -+ CABAC_ENTRY(409, -12, 69, -10, 83, -5, 70, -15, 81), -+ CABAC_ENTRY(410, -16, 70, -9, 71, -17, 75, -14, 80), -+ CABAC_ENTRY(411, -15, 67, -9, 67, -14, 72, 0, 68), -+ CABAC_ENTRY(412, -20, 62, -1, 61, -16, 67, -14, 70), -+ CABAC_ENTRY(413, -19, 70, -8, 66, -8, 53, -24, 56), -+ CABAC_ENTRY(414, -16, 66, -14, 66, -14, 59, -23, 68), -+ CABAC_ENTRY(415, -22, 65, 0, 59, -9, 52, -24, 50), -+ CABAC_ENTRY(416, -20, 63, 2, 59, -11, 68, -11, 74), -+ CABAC_ENTRY(417, 9, -2, 17, -10, 9, -2, 23, -13), -+ CABAC_ENTRY(418, 26, -9, 32, -13, 30, -10, 26, -13), -+ CABAC_ENTRY(419, 33, -9, 42, -9, 31, -4, 40, -15), -+ CABAC_ENTRY(420, 39, -7, 49, -5, 33, -1, 49, -14), -+ CABAC_ENTRY(421, 41, -2, 53, 0, 33, 7, 44, 3), -+ CABAC_ENTRY(422, 45, 3, 64, 3, 31, 12, 45, 6), -+ CABAC_ENTRY(423, 49, 9, 68, 10, 37, 23, 44, 34), -+ CABAC_ENTRY(424, 45, 27, 66, 27, 31, 38, 33, 54), -+ CABAC_ENTRY(425, 36, 59, 47, 57, 20, 64, 19, 82), -+ CABAC_ENTRY(426, -6, 66, -5, 71, -9, 71, -3, 75), -+ CABAC_ENTRY(427, -7, 35, 0, 24, -7, 37, -1, 23), -+ CABAC_ENTRY(428, -7, 42, -1, 36, -8, 44, 1, 34), -+ CABAC_ENTRY(429, -8, 45, -2, 42, -11, 49, 1, 43), -+ CABAC_ENTRY(430, -5, 48, -2, 52, -10, 56, 0, 54), -+ CABAC_ENTRY(431, -12, 56, -9, 57, -12, 59, -2, 55), -+ CABAC_ENTRY(432, -6, 60, -6, 63, -8, 63, 0, 61), -+ CABAC_ENTRY(433, -5, 62, -4, 65, -9, 67, 1, 64), -+ CABAC_ENTRY(434, -8, 66, -4, 67, -6, 68, 0, 68), -+ CABAC_ENTRY(435, -8, 76, -7, 82, -10, 79, -9, 92), -+ CABAC_ENTRY(436, -5, 85, -3, 81, -3, 78, -14, 106), -+ CABAC_ENTRY(437, -6, 81, -3, 76, -8, 74, -13, 97), -+ CABAC_ENTRY(438, -10, 77, -7, 72, -9, 72, -15, 90), -+ CABAC_ENTRY(439, -7, 81, -6, 78, -10, 72, -12, 90), -+ CABAC_ENTRY(440, -17, 80, -12, 72, -18, 75, -18, 88), -+ CABAC_ENTRY(441, -18, 73, -14, 68, -12, 71, -10, 73), -+ CABAC_ENTRY(442, -4, 74, -3, 70, -11, 63, -9, 79), -+ CABAC_ENTRY(443, -10, 83, -6, 76, -5, 70, -14, 86), -+ CABAC_ENTRY(444, -9, 71, -5, 66, -17, 75, -10, 73), -+ CABAC_ENTRY(445, -9, 67, -5, 62, -14, 72, -10, 70), -+ CABAC_ENTRY(446, -1, 61, 0, 57, -16, 67, -10, 69), -+ CABAC_ENTRY(447, -8, 66, -4, 61, -8, 53, -5, 66), -+ CABAC_ENTRY(448, -14, 66, -9, 60, -14, 59, -9, 64), -+ CABAC_ENTRY(449, 0, 59, 1, 54, -9, 52, -5, 58), -+ CABAC_ENTRY(450, 2, 59, 2, 58, -11, 68, 2, 59), -+ CABAC_ENTRY(451, 21, -13, 17, -10, 9, -2, 21, -10), -+ CABAC_ENTRY(452, 33, -14, 32, -13, 30, -10, 24, -11), -+ CABAC_ENTRY(453, 39, -7, 42, -9, 31, -4, 28, -8), -+ CABAC_ENTRY(454, 46, -2, 49, -5, 33, -1, 28, -1), -+ CABAC_ENTRY(455, 51, 2, 53, 0, 33, 7, 29, 3), -+ CABAC_ENTRY(456, 60, 6, 64, 3, 31, 12, 29, 9), -+ CABAC_ENTRY(457, 61, 17, 68, 10, 37, 23, 35, 20), -+ CABAC_ENTRY(458, 55, 34, 66, 27, 31, 38, 29, 36), -+ CABAC_ENTRY(459, 42, 62, 47, 57, 20, 64, 14, 67), -+}; -+ -+#endif /* RKVDEC_H264_CABAC_H_ */ --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0021-media-rockchip-Introduce-the-rkvdec2-driver.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0021-media-rockchip-Introduce-the-rkvdec2-driver.patch deleted file mode 100644 index 893b6adf80..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0021-media-rockchip-Introduce-the-rkvdec2-driver.patch +++ /dev/null @@ -1,2616 +0,0 @@ -From 7bae103b4a2e6d4b7e795ccdcddf201f352549b4 Mon Sep 17 00:00:00 2001 -From: Detlev Casanova <detlev.casanova@collabora.com> -Date: Fri, 14 Jun 2024 19:52:12 -0400 -Subject: [PATCH 21/63] media: rockchip: Introduce the rkvdec2 driver - -This driver supports the second generation of the Rockchip Video -decoder, also known as vdpu34x. -It is currently only used on the RK3588(s) SoC. - -There are 2 decoders on the RK3588 SoC that can work in pair to decode -8K video at 30 FPS but currently, only using one core at a time is -supported. - -Scheduling requests between the two cores will be implemented later. - -The core supports H264, HEVC, VP9 and AVS2 decoding but this driver -currently only supports H264. - -The driver is based on rkvdec and they may share some code in the -future. -The decision to make a different driver is mainly because rkvdec2 has -more features and can work with multiple cores. - -The registers are mapped in a struct in RAM using bitfields. It is IO -copied to the HW when all values are configured. -The decision to use such a struct instead of writing buffers one by one -is based on the following reasons: - - Rockchip cores are known to misbehave when registers are not written - in address order, - - Those cores also need the software to write all registers, even if - they are written their default values or are not related to the task - (this core will not start decoding some H264 frames if some VP9 - registers are not written to 0) - - In the future, to support multiple cores, the scheduler could be - optimized by storing the precomputed registers values and copy them - to the HW as soos as a core becomes available. - -This makes the code more readable and may bring performance improvements -in future features. - -Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com> ---- - drivers/media/platform/rockchip/Kconfig | 1 + - drivers/media/platform/rockchip/Makefile | 1 + - .../media/platform/rockchip/rkvdec2/Kconfig | 15 + - .../media/platform/rockchip/rkvdec2/Makefile | 3 + - .../platform/rockchip/rkvdec2/rkvdec2-h264.c | 744 ++++++++++ - .../platform/rockchip/rkvdec2/rkvdec2-regs.h | 346 +++++ - .../media/platform/rockchip/rkvdec2/rkvdec2.c | 1263 +++++++++++++++++ - .../media/platform/rockchip/rkvdec2/rkvdec2.h | 130 ++ - 8 files changed, 2503 insertions(+) - create mode 100644 drivers/media/platform/rockchip/rkvdec2/Kconfig - create mode 100644 drivers/media/platform/rockchip/rkvdec2/Makefile - create mode 100644 drivers/media/platform/rockchip/rkvdec2/rkvdec2-h264.c - create mode 100644 drivers/media/platform/rockchip/rkvdec2/rkvdec2-regs.h - create mode 100644 drivers/media/platform/rockchip/rkvdec2/rkvdec2.c - create mode 100644 drivers/media/platform/rockchip/rkvdec2/rkvdec2.h - -diff --git a/drivers/media/platform/rockchip/Kconfig b/drivers/media/platform/rockchip/Kconfig -index b41d3960c1b4..36987ef24014 100644 ---- a/drivers/media/platform/rockchip/Kconfig -+++ b/drivers/media/platform/rockchip/Kconfig -@@ -4,3 +4,4 @@ comment "Rockchip media platform drivers" - - source "drivers/media/platform/rockchip/rga/Kconfig" - source "drivers/media/platform/rockchip/rkisp1/Kconfig" -+source "drivers/media/platform/rockchip/rkvdec2/Kconfig" -diff --git a/drivers/media/platform/rockchip/Makefile b/drivers/media/platform/rockchip/Makefile -index 4f782b876ac9..8c108d91d13e 100644 ---- a/drivers/media/platform/rockchip/Makefile -+++ b/drivers/media/platform/rockchip/Makefile -@@ -1,3 +1,4 @@ - # SPDX-License-Identifier: GPL-2.0-only - obj-y += rga/ - obj-y += rkisp1/ -+obj-$(CONFIG_VIDEO_ROCKCHIP_VDEC2) += rkvdec2/ -diff --git a/drivers/media/platform/rockchip/rkvdec2/Kconfig b/drivers/media/platform/rockchip/rkvdec2/Kconfig -new file mode 100644 -index 000000000000..fd505cb7aff9 ---- /dev/null -+++ b/drivers/media/platform/rockchip/rkvdec2/Kconfig -@@ -0,0 +1,15 @@ -+# SPDX-License-Identifier: GPL-2.0 -+config VIDEO_ROCKCHIP_VDEC2 -+ tristate "Rockchip Video Decoder driver 2" -+ depends on ARCH_ROCKCHIP || COMPILE_TEST -+ depends on VIDEO_DEV -+ select MEDIA_CONTROLLER -+ select VIDEOBUF2_DMA_CONTIG -+ select VIDEOBUF2_VMALLOC -+ select V4L2_MEM2MEM_DEV -+ select V4L2_H264 -+ help -+ Support for the Rockchip Video Decoder 2 IP present on Rockchip SoCs, -+ which accelerates video decoding. -+ To compile this driver as a module, choose M here: the module -+ will be called rockchip-vdec2. -diff --git a/drivers/media/platform/rockchip/rkvdec2/Makefile b/drivers/media/platform/rockchip/rkvdec2/Makefile -new file mode 100644 -index 000000000000..b5a6ac701970 ---- /dev/null -+++ b/drivers/media/platform/rockchip/rkvdec2/Makefile -@@ -0,0 +1,3 @@ -+obj-$(CONFIG_VIDEO_ROCKCHIP_VDEC2) += rockchip-vdec2.o -+ -+rockchip-vdec2-y += rkvdec2.o rkvdec2-h264.o -diff --git a/drivers/media/platform/rockchip/rkvdec2/rkvdec2-h264.c b/drivers/media/platform/rockchip/rkvdec2/rkvdec2-h264.c -new file mode 100644 -index 000000000000..2e991c85d90e ---- /dev/null -+++ b/drivers/media/platform/rockchip/rkvdec2/rkvdec2-h264.c -@@ -0,0 +1,744 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Rockchip Video Decoder 2 H264 backend -+ * -+ * Copyright (C) 2024 Collabora, Ltd. -+ * Detlev Casanova <detlev.casanova@collabora.com> -+ * -+ * Based on rkvdec driver by Boris Brezillon <boris.brezillon@collabora.com> -+ */ -+ -+#include <media/v4l2-h264.h> -+#include <media/v4l2-mem2mem.h> -+#include <media/v4l2-cabac/rkvdec-cabac.h> -+ -+#include "rkvdec2.h" -+#include "rkvdec2-regs.h" -+ -+#define RKVDEC_NUM_REFLIST 3 -+ -+struct rkvdec2_h264_scaling_list { -+ u8 scaling_list_4x4[6][16]; -+ u8 scaling_list_8x8[6][64]; -+ u8 padding[128]; -+}; -+ -+struct rkvdec2_sps { -+ u16 seq_parameter_set_id: 4; -+ u16 profile_idc: 8; -+ u16 constraint_set3_flag: 1; -+ u16 chroma_format_idc: 2; -+ u16 bit_depth_luma: 3; -+ u16 bit_depth_chroma: 3; -+ u16 qpprime_y_zero_transform_bypass_flag: 1; -+ u16 log2_max_frame_num_minus4: 4; -+ u16 max_num_ref_frames: 5; -+ u16 pic_order_cnt_type: 2; -+ u16 log2_max_pic_order_cnt_lsb_minus4: 4; -+ u16 delta_pic_order_always_zero_flag: 1; -+ u16 pic_width_in_mbs: 12; -+ u16 pic_height_in_mbs: 12; -+ u16 frame_mbs_only_flag: 1; -+ u16 mb_adaptive_frame_field_flag: 1; -+ u16 direct_8x8_inference_flag: 1; -+ u16 mvc_extension_enable: 1; -+ u16 num_views: 2; -+ -+ u16 reserved_bits: 12; -+ u16 reserved[11]; -+} __packed; -+ -+struct rkvdec2_pps { -+ u16 pic_parameter_set_id: 8; -+ u16 pps_seq_parameter_set_id: 5; -+ u16 entropy_coding_mode_flag: 1; -+ u16 bottom_field_pic_order_in_frame_present_flag: 1; -+ u16 num_ref_idx_l0_default_active_minus1: 5; -+ u16 num_ref_idx_l1_default_active_minus1: 5; -+ u16 weighted_pred_flag: 1; -+ u16 weighted_bipred_idc: 2; -+ u16 pic_init_qp_minus26: 7; -+ u16 pic_init_qs_minus26: 6; -+ u16 chroma_qp_index_offset: 5; -+ u16 deblocking_filter_control_present_flag: 1; -+ u16 constrained_intra_pred_flag: 1; -+ u16 redundant_pic_cnt_present: 1; -+ u16 transform_8x8_mode_flag: 1; -+ u16 second_chroma_qp_index_offset: 5; -+ u16 scaling_list_enable_flag: 1; -+ u32 scaling_list_address; -+ u16 is_longterm; -+ -+ u8 reserved[3]; -+} __packed; -+ -+struct rkvdec2_rps_entry { -+ u32 dpb_info0: 5; -+ u32 bottom_flag0: 1; -+ u32 view_index_off0: 1; -+ u32 dpb_info1: 5; -+ u32 bottom_flag1: 1; -+ u32 view_index_off1: 1; -+ u32 dpb_info2: 5; -+ u32 bottom_flag2: 1; -+ u32 view_index_off2: 1; -+ u32 dpb_info3: 5; -+ u32 bottom_flag3: 1; -+ u32 view_index_off3: 1; -+ u32 dpb_info4: 5; -+ u32 bottom_flag4: 1; -+ u32 view_index_off4: 1; -+ u32 dpb_info5: 5; -+ u32 bottom_flag5: 1; -+ u32 view_index_off5: 1; -+ u32 dpb_info6: 5; -+ u32 bottom_flag6: 1; -+ u32 view_index_off6: 1; -+ u32 dpb_info7: 5; -+ u32 bottom_flag7: 1; -+ u32 view_index_off7: 1; -+} __packed; -+ -+struct rkvdec2_rps { -+ u16 frame_num[16]; -+ u32 reserved0; -+ struct rkvdec2_rps_entry entries[12]; -+ u32 reserved1[66]; -+} __packed; -+ -+struct rkvdec2_sps_pps { -+ struct rkvdec2_sps sps; -+ struct rkvdec2_pps pps; -+} __packed; -+ -+/* Data structure describing auxiliary buffer format. */ -+struct rkvdec2_h264_priv_tbl { -+ u32 cabac_table[4][464][2]; -+ struct rkvdec2_h264_scaling_list scaling_list; -+ struct rkvdec2_sps_pps param_set[256]; -+ struct rkvdec2_rps rps; -+}; -+ -+struct rkvdec2_h264_reflists { -+ struct v4l2_h264_reference p[V4L2_H264_REF_LIST_LEN]; -+ struct v4l2_h264_reference b0[V4L2_H264_REF_LIST_LEN]; -+ struct v4l2_h264_reference b1[V4L2_H264_REF_LIST_LEN]; -+}; -+ -+struct rkvdec2_h264_run { -+ struct rkvdec2_run base; -+ const struct v4l2_ctrl_h264_decode_params *decode_params; -+ const struct v4l2_ctrl_h264_sps *sps; -+ const struct v4l2_ctrl_h264_pps *pps; -+ const struct v4l2_ctrl_h264_scaling_matrix *scaling_matrix; -+ struct vb2_buffer *ref_buf[V4L2_H264_NUM_DPB_ENTRIES]; -+}; -+ -+struct rkvdec2_h264_ctx { -+ struct rkvdec2_aux_buf priv_tbl; -+ struct rkvdec2_h264_reflists reflists; -+ struct rkvdec2_regs_h264 regs; -+}; -+ -+static void assemble_hw_pps(struct rkvdec2_ctx *ctx, -+ struct rkvdec2_h264_run *run) -+{ -+ struct rkvdec2_h264_ctx *h264_ctx = ctx->priv; -+ const struct v4l2_ctrl_h264_sps *sps = run->sps; -+ const struct v4l2_ctrl_h264_pps *pps = run->pps; -+ const struct v4l2_ctrl_h264_decode_params *dec_params = run->decode_params; -+ const struct v4l2_h264_dpb_entry *dpb = dec_params->dpb; -+ struct rkvdec2_h264_priv_tbl *priv_tbl = h264_ctx->priv_tbl.cpu; -+ struct rkvdec2_sps_pps *hw_ps; -+ dma_addr_t scaling_list_address; -+ u32 scaling_distance; -+ u32 i; -+ -+ /* -+ * HW read the SPS/PPS information from PPS packet index by PPS id. -+ * offset from the base can be calculated by PPS_id * 32 (size per PPS -+ * packet unit). so the driver copy SPS/PPS information to the exact PPS -+ * packet unit for HW accessing. -+ */ -+ hw_ps = &priv_tbl->param_set[pps->pic_parameter_set_id]; -+ memset(hw_ps, 0, sizeof(*hw_ps)); -+ -+ /* write sps */ -+ hw_ps->sps.seq_parameter_set_id = sps->seq_parameter_set_id; -+ hw_ps->sps.profile_idc = sps->profile_idc; -+ hw_ps->sps.constraint_set3_flag = !!(sps->constraint_set_flags & (1 << 3)); -+ hw_ps->sps.chroma_format_idc = sps->chroma_format_idc; -+ hw_ps->sps.bit_depth_luma = sps->bit_depth_luma_minus8; -+ hw_ps->sps.bit_depth_chroma = sps->bit_depth_chroma_minus8; -+ hw_ps->sps.qpprime_y_zero_transform_bypass_flag = !!(sps->flags & V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS); -+ hw_ps->sps.log2_max_frame_num_minus4 = sps->log2_max_frame_num_minus4; -+ hw_ps->sps.max_num_ref_frames = sps->max_num_ref_frames; -+ hw_ps->sps.pic_order_cnt_type = sps->pic_order_cnt_type; -+ hw_ps->sps.log2_max_pic_order_cnt_lsb_minus4 = -+ sps->log2_max_pic_order_cnt_lsb_minus4; -+ hw_ps->sps.delta_pic_order_always_zero_flag = -+ !!(sps->flags & V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO); -+ hw_ps->sps.mvc_extension_enable = 1; -+ hw_ps->sps.num_views = 1; -+ -+ /* -+ * Use the SPS values since they are already in macroblocks -+ * dimensions, height can be field height (halved) if -+ * V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY is not set and also it allows -+ * decoding smaller images into larger allocation which can be used -+ * to implementing SVC spatial layer support. -+ */ -+ hw_ps->sps.pic_width_in_mbs = sps->pic_width_in_mbs_minus1 + 1; -+ hw_ps->sps.pic_height_in_mbs = sps->pic_height_in_map_units_minus1 + 1; -+ hw_ps->sps.frame_mbs_only_flag = -+ !!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY); -+ hw_ps->sps.mb_adaptive_frame_field_flag = -+ !!(sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD); -+ hw_ps->sps.direct_8x8_inference_flag = -+ !!(sps->flags & V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE); -+ -+ /* write pps */ -+ hw_ps->pps.pic_parameter_set_id = pps->pic_parameter_set_id; -+ hw_ps->pps.pps_seq_parameter_set_id = pps->seq_parameter_set_id; -+ hw_ps->pps.entropy_coding_mode_flag = -+ !!(pps->flags & V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE); -+ hw_ps->pps.bottom_field_pic_order_in_frame_present_flag = -+ !!(pps->flags & V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT); -+ hw_ps->pps.num_ref_idx_l0_default_active_minus1 = -+ pps->num_ref_idx_l0_default_active_minus1; -+ hw_ps->pps.num_ref_idx_l1_default_active_minus1 = -+ pps->num_ref_idx_l1_default_active_minus1; -+ hw_ps->pps.weighted_pred_flag = -+ !!(pps->flags & V4L2_H264_PPS_FLAG_WEIGHTED_PRED); -+ hw_ps->pps.weighted_bipred_idc = pps->weighted_bipred_idc; -+ hw_ps->pps.pic_init_qp_minus26 = pps->pic_init_qp_minus26; -+ hw_ps->pps.pic_init_qs_minus26 = pps->pic_init_qs_minus26; -+ hw_ps->pps.chroma_qp_index_offset = pps->chroma_qp_index_offset; -+ hw_ps->pps.deblocking_filter_control_present_flag = -+ !!(pps->flags & V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT); -+ hw_ps->pps.constrained_intra_pred_flag = -+ !!(pps->flags & V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED); -+ hw_ps->pps.redundant_pic_cnt_present = -+ !!(pps->flags & V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT); -+ hw_ps->pps.transform_8x8_mode_flag = -+ !!(pps->flags & V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE); -+ hw_ps->pps.second_chroma_qp_index_offset = pps->second_chroma_qp_index_offset; -+ hw_ps->pps.scaling_list_enable_flag = -+ !!(pps->flags & V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT); -+ -+ /* -+ * To be on the safe side, program the scaling matrix address -+ * -+ * With this set here, -+ * RKVDEC_SWREG12_SENCODARY_EN:sw_scanlist_addr_valid_en -+ * can stay at 0 -+ */ -+ scaling_distance = offsetof(struct rkvdec2_h264_priv_tbl, scaling_list); -+ scaling_list_address = h264_ctx->priv_tbl.dma + scaling_distance; -+ hw_ps->pps.scaling_list_address = scaling_list_address; -+ -+ for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) { -+ if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) -+ hw_ps->pps.is_longterm |= (1 << i); -+ } -+} -+ -+static void lookup_ref_buf_idx(struct rkvdec2_ctx *ctx, -+ struct rkvdec2_h264_run *run) -+{ -+ const struct v4l2_ctrl_h264_decode_params *dec_params = run->decode_params; -+ u32 i; -+ -+ for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) { -+ struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx; -+ const struct v4l2_h264_dpb_entry *dpb = run->decode_params->dpb; -+ struct vb2_queue *cap_q = &m2m_ctx->cap_q_ctx.q; -+ struct vb2_buffer *buf = NULL; -+ -+ if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE) { -+ buf = vb2_find_buffer(cap_q, dpb[i].reference_ts); -+ if (!buf) { -+ dev_dbg(ctx->dev->dev, "No buffer for reference_ts %llu", -+ dpb[i].reference_ts); -+ } -+ } -+ -+ run->ref_buf[i] = buf; -+ } -+} -+ -+static void set_dpb_info(struct rkvdec2_rps_entry *entries, -+ u8 reflist, -+ u8 refnum, -+ u8 info, -+ bool bottom) -+{ -+ struct rkvdec2_rps_entry *entry = &entries[(reflist * 4) + refnum / 8]; -+ u8 idx = refnum % 8; -+ -+ switch (idx) { -+ case 0: -+ entry->dpb_info0 = info; -+ entry->bottom_flag0 = bottom; -+ break; -+ case 1: -+ entry->dpb_info1 = info; -+ entry->bottom_flag1 = bottom; -+ break; -+ case 2: -+ entry->dpb_info2 = info; -+ entry->bottom_flag2 = bottom; -+ break; -+ case 3: -+ entry->dpb_info3 = info; -+ entry->bottom_flag3 = bottom; -+ break; -+ case 4: -+ entry->dpb_info4 = info; -+ entry->bottom_flag4 = bottom; -+ break; -+ case 5: -+ entry->dpb_info5 = info; -+ entry->bottom_flag5 = bottom; -+ break; -+ case 6: -+ entry->dpb_info6 = info; -+ entry->bottom_flag6 = bottom; -+ break; -+ case 7: -+ entry->dpb_info7 = info; -+ entry->bottom_flag7 = bottom; -+ break; -+ } -+} -+ -+static void assemble_hw_rps(struct rkvdec2_ctx *ctx, -+ struct v4l2_h264_reflist_builder *builder, -+ struct rkvdec2_h264_run *run) -+{ -+ const struct v4l2_ctrl_h264_decode_params *dec_params = run->decode_params; -+ const struct v4l2_h264_dpb_entry *dpb = dec_params->dpb; -+ struct rkvdec2_h264_ctx *h264_ctx = ctx->priv; -+ struct rkvdec2_h264_priv_tbl *priv_tbl = h264_ctx->priv_tbl.cpu; -+ -+ struct rkvdec2_rps *hw_rps = &priv_tbl->rps; -+ u32 i, j; -+ -+ memset(hw_rps, 0, sizeof(priv_tbl->rps)); -+ -+ /* -+ * Assign an invalid pic_num if DPB entry at that position is inactive. -+ * If we assign 0 in that position hardware will treat that as a real -+ * reference picture with pic_num 0, triggering output picture -+ * corruption. -+ */ -+ for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) { -+ if (!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)) -+ continue; -+ -+ hw_rps->frame_num[i] = builder->refs[i].frame_num; -+ } -+ -+ for (j = 0; j < RKVDEC_NUM_REFLIST; j++) { -+ for (i = 0; i < builder->num_valid; i++) { -+ struct v4l2_h264_reference *ref; -+ bool dpb_valid; -+ bool bottom; -+ -+ switch (j) { -+ case 0: -+ ref = &h264_ctx->reflists.p[i]; -+ break; -+ case 1: -+ ref = &h264_ctx->reflists.b0[i]; -+ break; -+ case 2: -+ ref = &h264_ctx->reflists.b1[i]; -+ break; -+ } -+ -+ if (WARN_ON(ref->index >= ARRAY_SIZE(dec_params->dpb))) -+ continue; -+ -+ dpb_valid = !!(run->ref_buf[ref->index]); -+ bottom = ref->fields == V4L2_H264_BOTTOM_FIELD_REF; -+ -+ set_dpb_info(hw_rps->entries, j, i, ref->index | (dpb_valid << 4), bottom); -+ } -+ } -+} -+ -+static void assemble_hw_scaling_list(struct rkvdec2_ctx *ctx, -+ struct rkvdec2_h264_run *run) -+{ -+ const struct v4l2_ctrl_h264_scaling_matrix *scaling = run->scaling_matrix; -+ const struct v4l2_ctrl_h264_pps *pps = run->pps; -+ struct rkvdec2_h264_ctx *h264_ctx = ctx->priv; -+ struct rkvdec2_h264_priv_tbl *tbl = h264_ctx->priv_tbl.cpu; -+ -+ if (!(pps->flags & V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT)) -+ return; -+ -+ BUILD_BUG_ON(sizeof(tbl->scaling_list.scaling_list_4x4) != -+ sizeof(scaling->scaling_list_4x4)); -+ BUILD_BUG_ON(sizeof(tbl->scaling_list.scaling_list_8x8) != -+ sizeof(scaling->scaling_list_8x8)); -+ -+ memcpy(tbl->scaling_list.scaling_list_4x4, -+ scaling->scaling_list_4x4, -+ sizeof(scaling->scaling_list_4x4)); -+ -+ memcpy(tbl->scaling_list.scaling_list_8x8, -+ scaling->scaling_list_8x8, -+ sizeof(scaling->scaling_list_8x8)); -+} -+ -+static inline void rkvdec2_memcpy_toio(void __iomem *dst, void *src, size_t len) -+{ -+#ifdef CONFIG_ARM64 -+ __iowrite32_copy(dst, src, len); -+#else -+ memcpy_toio(dst, src, len); -+#endif -+} -+ -+static void rkvdec2_write_regs(struct rkvdec2_ctx *ctx) -+{ -+ struct rkvdec2_dev *rkvdec = ctx->dev; -+ struct rkvdec2_h264_ctx *h264_ctx = ctx->priv; -+ -+ rkvdec2_memcpy_toio(rkvdec->regs + OFFSET_COMMON_REGS, -+ &h264_ctx->regs.common, -+ sizeof(h264_ctx->regs.common)); -+ rkvdec2_memcpy_toio(rkvdec->regs + OFFSET_CODEC_PARAMS_REGS, -+ &h264_ctx->regs.h264_param, -+ sizeof(h264_ctx->regs.h264_param)); -+ rkvdec2_memcpy_toio(rkvdec->regs + OFFSET_COMMON_ADDR_REGS, -+ &h264_ctx->regs.common_addr, -+ sizeof(h264_ctx->regs.common_addr)); -+ rkvdec2_memcpy_toio(rkvdec->regs + OFFSET_CODEC_ADDR_REGS, -+ &h264_ctx->regs.h264_addr, -+ sizeof(h264_ctx->regs.h264_addr)); -+ rkvdec2_memcpy_toio(rkvdec->regs + OFFSET_POC_HIGHBIT_REGS, -+ &h264_ctx->regs.h264_highpoc, -+ sizeof(h264_ctx->regs.h264_highpoc)); -+} -+ -+static void config_registers(struct rkvdec2_ctx *ctx, -+ struct rkvdec2_h264_run *run) -+{ -+ const struct v4l2_ctrl_h264_decode_params *dec_params = run->decode_params; -+ const struct v4l2_ctrl_h264_sps *sps = run->sps; -+ const struct v4l2_h264_dpb_entry *dpb = dec_params->dpb; -+ struct rkvdec2_h264_ctx *h264_ctx = ctx->priv; -+ dma_addr_t priv_start_addr = h264_ctx->priv_tbl.dma; -+ const struct v4l2_pix_format_mplane *dst_fmt; -+ struct vb2_v4l2_buffer *src_buf = run->base.bufs.src; -+ struct vb2_v4l2_buffer *dst_buf = run->base.bufs.dst; -+ struct rkvdec2_regs_h264 *regs = &h264_ctx->regs; -+ const struct v4l2_format *f; -+ dma_addr_t rlc_addr; -+ dma_addr_t dst_addr; -+ u32 hor_virstride = 0; -+ u32 ver_virstride = 0; -+ u32 y_virstride = 0; -+ u32 offset; -+ u32 pixels; -+ u32 i; -+ -+ memset(regs, 0, sizeof(*regs)); -+ -+ /* Set H264 mode */ -+ regs->common.reg009.dec_mode = RKVDEC2_MODE_H264; -+ -+ /* Set config */ -+ regs->common.reg011.buf_empty_en = 1; -+ regs->common.reg011.dec_clkgate_e = 1; -+ regs->common.reg011.dec_timeout_e = 1; -+ regs->common.reg011.pix_range_detection_e = 1; -+ -+ /* Set IDR flag */ -+ regs->common.reg013.cur_pic_is_idr = -+ !!(dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC); -+ -+ /* Set input stream length */ -+ regs->common.stream_len = vb2_get_plane_payload(&src_buf->vb2_buf, 0); -+ -+ /* Set max slice number */ -+ regs->common.reg017.slice_num = MAX_SLICE_NUMBER; -+ -+ /* Set strides */ -+ f = &ctx->decoded_fmt; -+ dst_fmt = &f->fmt.pix_mp; -+ hor_virstride = (sps->bit_depth_luma_minus8 + 8) * dst_fmt->width / 8; -+ ver_virstride = round_up(dst_fmt->height, 16); -+ y_virstride = hor_virstride * ver_virstride; -+ pixels = dst_fmt->height * dst_fmt->width; -+ -+ regs->common.reg018.y_hor_virstride = hor_virstride / 16; -+ regs->common.reg019.uv_hor_virstride = hor_virstride / 16; -+ regs->common.reg020.y_virstride = y_virstride / 16; -+ -+ /* Activate block gating */ -+ regs->common.reg026.swreg_block_gating_e = 0xfffef; -+ regs->common.reg026.reg_cfg_gating_en = 1; -+ -+ /* Set timeout threshold */ -+ if (pixels < RKVDEC2_1080P_PIXELS) -+ regs->common.timeout_threshold = RKVDEC2_TIMEOUT_1080p; -+ else if (pixels < RKVDEC2_4K_PIXELS) -+ regs->common.timeout_threshold = RKVDEC2_TIMEOUT_4K; -+ else if (pixels < RKVDEC2_8K_PIXELS) -+ regs->common.timeout_threshold = RKVDEC2_TIMEOUT_8K; -+ else -+ regs->common.timeout_threshold = RKVDEC2_TIMEOUT_MAX; -+ -+ /* Set TOP and BOTTOM POCs */ -+ regs->h264_param.cur_top_poc = dec_params->top_field_order_cnt; -+ regs->h264_param.cur_bot_poc = dec_params->bottom_field_order_cnt; -+ -+ /* Set ref pic address & poc */ -+ for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) { -+ struct vb2_buffer *vb_buf = run->ref_buf[i]; -+ dma_addr_t buf_dma; -+ -+ /* -+ * If a DPB entry is unused or invalid, address of current destination -+ * buffer is returned. -+ */ -+ if (!vb_buf) -+ vb_buf = &dst_buf->vb2_buf; -+ -+ buf_dma = vb2_dma_contig_plane_dma_addr(vb_buf, 0); -+ -+ /* Set reference addresses */ -+ regs->h264_addr.ref_base[i] = buf_dma; -+ -+ /* Set COLMV addresses */ -+ regs->h264_addr.colmv_base[i] = buf_dma + ctx->colmv_offset; -+ -+ struct rkvdec2_h264_ref_info *ref_info = -+ ®s->h264_param.ref_info_regs[i / 4].ref_info[i % 4]; -+ -+ ref_info->ref_field = -+ !!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_FIELD); -+ ref_info->ref_colmv_use_flag = -+ !!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE); -+ ref_info->ref_topfield_used = -+ !!(dpb[i].fields & V4L2_H264_TOP_FIELD_REF); -+ ref_info->ref_botfield_used = -+ !!(dpb[i].fields & V4L2_H264_BOTTOM_FIELD_REF); -+ -+ regs->h264_param.ref_pocs[i * 2] = -+ dpb[i].top_field_order_cnt; -+ regs->h264_param.ref_pocs[i * 2 + 1] = -+ dpb[i].bottom_field_order_cnt; -+ } -+ -+ /* Set rlc base address (input stream) */ -+ rlc_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0); -+ regs->common_addr.rlc_base = rlc_addr; -+ regs->common_addr.rlcwrite_base = rlc_addr; -+ -+ /* Set output base address */ -+ dst_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0); -+ regs->common_addr.decout_base = dst_addr; -+ -+ /* Set colmv address */ -+ regs->common_addr.colmv_cur_base = dst_addr + ctx->colmv_offset; -+ -+ /* Set RCB addresses */ -+ for (i = 0; i < RKVDEC2_RCB_COUNT; i++) -+ regs->common_addr.rcb_base[i] = ctx->rcb_bufs[i].dma; -+ -+ /* Set hw pps address */ -+ offset = offsetof(struct rkvdec2_h264_priv_tbl, param_set); -+ regs->h264_addr.pps_base = priv_start_addr + offset; -+ -+ /* Set hw rps address */ -+ offset = offsetof(struct rkvdec2_h264_priv_tbl, rps); -+ regs->h264_addr.rps_base = priv_start_addr + offset; -+ -+ /* Set cabac table */ -+ offset = offsetof(struct rkvdec2_h264_priv_tbl, cabac_table); -+ regs->h264_addr.cabactbl_base = priv_start_addr + offset; -+ -+ rkvdec2_write_regs(ctx); -+} -+ -+#define RKVDEC_H264_MAX_DEPTH_IN_BYTES 2 -+ -+static int rkvdec2_h264_adjust_fmt(struct rkvdec2_ctx *ctx, -+ struct v4l2_format *f) -+{ -+ struct v4l2_pix_format_mplane *fmt = &f->fmt.pix_mp; -+ -+ fmt->num_planes = 1; -+ if (!fmt->plane_fmt[0].sizeimage) -+ fmt->plane_fmt[0].sizeimage = fmt->width * fmt->height * -+ RKVDEC_H264_MAX_DEPTH_IN_BYTES; -+ return 0; -+} -+ -+static int rkvdec2_h264_validate_sps(struct rkvdec2_ctx *ctx, -+ const struct v4l2_ctrl_h264_sps *sps) -+{ -+ unsigned int width, height; -+ -+ /* -+ * TODO: The hardware supports 10-bit and 4:2:2 profiles, -+ * but it's currently broken in the driver. -+ * Reject them for now, until it's fixed. -+ */ -+ if (sps->chroma_format_idc > 1) -+ /* Only 4:0:0 and 4:2:0 are supported */ -+ return -EINVAL; -+ if (sps->bit_depth_luma_minus8 != sps->bit_depth_chroma_minus8) -+ /* Luma and chroma bit depth mismatch */ -+ return -EINVAL; -+ if (sps->bit_depth_luma_minus8 != 0) -+ /* Only 8-bit is supported */ -+ return -EINVAL; -+ -+ width = (sps->pic_width_in_mbs_minus1 + 1) * 16; -+ height = (sps->pic_height_in_map_units_minus1 + 1) * 16; -+ -+ /* -+ * When frame_mbs_only_flag is not set, this is field height, -+ * which is half the final height (see (7-8) in the -+ * specification) -+ */ -+ if (!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY)) -+ height *= 2; -+ -+ if (width > ctx->coded_fmt.fmt.pix_mp.width || -+ height > ctx->coded_fmt.fmt.pix_mp.height) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static int rkvdec2_h264_start(struct rkvdec2_ctx *ctx) -+{ -+ struct rkvdec2_dev *rkvdec = ctx->dev; -+ struct rkvdec2_h264_priv_tbl *priv_tbl; -+ struct rkvdec2_h264_ctx *h264_ctx; -+ struct v4l2_ctrl *ctrl; -+ int ret; -+ -+ ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, -+ V4L2_CID_STATELESS_H264_SPS); -+ if (!ctrl) -+ return -EINVAL; -+ -+ ret = rkvdec2_h264_validate_sps(ctx, ctrl->p_new.p_h264_sps); -+ if (ret) -+ return ret; -+ -+ h264_ctx = kzalloc(sizeof(*h264_ctx), GFP_KERNEL); -+ if (!h264_ctx) -+ return -ENOMEM; -+ -+ priv_tbl = dma_alloc_coherent(rkvdec->dev, sizeof(*priv_tbl), -+ &h264_ctx->priv_tbl.dma, GFP_KERNEL); -+ if (!priv_tbl) { -+ ret = -ENOMEM; -+ goto err_free_ctx; -+ } -+ -+ h264_ctx->priv_tbl.size = sizeof(*priv_tbl); -+ h264_ctx->priv_tbl.cpu = priv_tbl; -+ memcpy(priv_tbl->cabac_table, rkvdec_h264_cabac_table, -+ sizeof(rkvdec_h264_cabac_table)); -+ -+ ctx->priv = h264_ctx; -+ return 0; -+ -+err_free_ctx: -+ kfree(h264_ctx); -+ return ret; -+} -+ -+static void rkvdec2_h264_stop(struct rkvdec2_ctx *ctx) -+{ -+ struct rkvdec2_h264_ctx *h264_ctx = ctx->priv; -+ struct rkvdec2_dev *rkvdec = ctx->dev; -+ -+ dma_free_coherent(rkvdec->dev, h264_ctx->priv_tbl.size, -+ h264_ctx->priv_tbl.cpu, h264_ctx->priv_tbl.dma); -+ kfree(h264_ctx); -+} -+ -+static void rkvdec2_h264_run_preamble(struct rkvdec2_ctx *ctx, -+ struct rkvdec2_h264_run *run) -+{ -+ struct v4l2_ctrl *ctrl; -+ -+ ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, -+ V4L2_CID_STATELESS_H264_DECODE_PARAMS); -+ run->decode_params = ctrl ? ctrl->p_cur.p : NULL; -+ ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, -+ V4L2_CID_STATELESS_H264_SPS); -+ run->sps = ctrl ? ctrl->p_cur.p : NULL; -+ ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, -+ V4L2_CID_STATELESS_H264_PPS); -+ run->pps = ctrl ? ctrl->p_cur.p : NULL; -+ ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, -+ V4L2_CID_STATELESS_H264_SCALING_MATRIX); -+ run->scaling_matrix = ctrl ? ctrl->p_cur.p : NULL; -+ -+ rkvdec2_run_preamble(ctx, &run->base); -+} -+ -+static int rkvdec2_h264_run(struct rkvdec2_ctx *ctx) -+{ -+ struct v4l2_h264_reflist_builder reflist_builder; -+ struct rkvdec2_dev *rkvdec = ctx->dev; -+ struct rkvdec2_h264_ctx *h264_ctx = ctx->priv; -+ struct rkvdec2_h264_run run; -+ uint32_t watchdog_time; -+ -+ rkvdec2_h264_run_preamble(ctx, &run); -+ -+ /* Build the P/B{0,1} ref lists. */ -+ v4l2_h264_init_reflist_builder(&reflist_builder, run.decode_params, -+ run.sps, run.decode_params->dpb); -+ v4l2_h264_build_p_ref_list(&reflist_builder, h264_ctx->reflists.p); -+ v4l2_h264_build_b_ref_lists(&reflist_builder, h264_ctx->reflists.b0, -+ h264_ctx->reflists.b1); -+ -+ assemble_hw_scaling_list(ctx, &run); -+ assemble_hw_pps(ctx, &run); -+ lookup_ref_buf_idx(ctx, &run); -+ assemble_hw_rps(ctx, &reflist_builder, &run); -+ -+ config_registers(ctx, &run); -+ -+ rkvdec2_run_postamble(ctx, &run.base); -+ -+ /* Set watchdog at 2 times the hardware timeout threshold */ -+ u64 timeout_threshold = h264_ctx->regs.common.timeout_threshold; -+ watchdog_time = 2 * (1000 * timeout_threshold) / clk_get_rate(rkvdec->clocks[0].clk); -+ schedule_delayed_work(&rkvdec->watchdog_work, msecs_to_jiffies(watchdog_time)); -+ -+ /* Start decoding! */ -+ writel(RKVDEC2_REG_DEC_E_BIT, rkvdec->regs + RKVDEC2_REG_DEC_E); -+ -+ return 0; -+} -+ -+static int rkvdec2_h264_try_ctrl(struct rkvdec2_ctx *ctx, struct v4l2_ctrl *ctrl) -+{ -+ if (ctrl->id == V4L2_CID_STATELESS_H264_SPS) -+ return rkvdec2_h264_validate_sps(ctx, ctrl->p_new.p_h264_sps); -+ -+ return 0; -+} -+ -+const struct rkvdec2_coded_fmt_ops rkvdec2_h264_fmt_ops = { -+ .adjust_fmt = rkvdec2_h264_adjust_fmt, -+ .start = rkvdec2_h264_start, -+ .stop = rkvdec2_h264_stop, -+ .run = rkvdec2_h264_run, -+ .try_ctrl = rkvdec2_h264_try_ctrl, -+}; -diff --git a/drivers/media/platform/rockchip/rkvdec2/rkvdec2-regs.h b/drivers/media/platform/rockchip/rkvdec2/rkvdec2-regs.h -new file mode 100644 -index 000000000000..2a432fc0bf52 ---- /dev/null -+++ b/drivers/media/platform/rockchip/rkvdec2/rkvdec2-regs.h -@@ -0,0 +1,346 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Rockchip Video Decoder 2 driver registers description -+ * -+ * Copyright (C) 2024 Collabora, Ltd. -+ * Detlev Casanova <detlev.casanova@collabora.com> -+ */ -+ -+#ifndef _RKVDEC_REGS_H_ -+#define _RKVDEC_REGS_H_ -+ -+#define OFFSET_COMMON_REGS (8 * sizeof(u32)) -+#define OFFSET_CODEC_PARAMS_REGS (64 * sizeof(u32)) -+#define OFFSET_COMMON_ADDR_REGS (128 * sizeof(u32)) -+#define OFFSET_CODEC_ADDR_REGS (160 * sizeof(u32)) -+#define OFFSET_POC_HIGHBIT_REGS (200 * sizeof(u32)) -+ -+#define RKVDEC2_MODE_HEVC 0 -+#define RKVDEC2_MODE_H264 1 -+#define RKVDEC2_MODE_VP9 2 -+#define RKVDEC2_MODE_AVS2 3 -+ -+#define MAX_SLICE_NUMBER 0x3fff -+ -+#define RKVDEC2_1080P_PIXELS (1920 * 1080) -+#define RKVDEC2_4K_PIXELS (4096 * 2304) -+#define RKVDEC2_8K_PIXELS (7680 * 4320) -+#define RKVDEC2_TIMEOUT_1080p (0xefffff) -+#define RKVDEC2_TIMEOUT_4K (0x2cfffff) -+#define RKVDEC2_TIMEOUT_8K (0x4ffffff) -+#define RKVDEC2_TIMEOUT_MAX (0xffffffff) -+ -+#define RKVDEC2_REG_DEC_E 0x028 -+#define RKVDEC2_REG_DEC_E_BIT 1 -+ -+#define RKVDEC2_REG_IMPORTANT_EN 0x02c -+#define RKVDEC2_REG_DEC_IRQ_DISABLE BIT(4) -+ -+#define RKVDEC2_REG_STA_INT 0x380 -+#define STA_INT_DEC_RDY_STA BIT(2) -+ -+/* base: OFFSET_COMMON_REGS */ -+struct rkvdec2_regs_common { -+ struct rkvdec2_in_out { -+ u32 in_endian : 1; -+ u32 in_swap32_e : 1; -+ u32 in_swap64_e : 1; -+ u32 str_endian : 1; -+ u32 str_swap32_e : 1; -+ u32 str_swap64_e : 1; -+ u32 out_endian : 1; -+ u32 out_swap32_e : 1; -+ u32 out_cbcr_swap : 1; -+ u32 out_swap64_e : 1; -+ u32 reserved : 22; -+ } reg008; -+ -+ struct rkvdec2_dec_mode { -+ u32 dec_mode : 10; -+ u32 reserved : 22; -+ } reg009; -+ -+ struct rkvdec2_dec_e { -+ u32 dec_e : 1; -+ u32 reserved : 31; -+ } reg010; -+ -+ struct rkvdec2_important_en { -+ u32 reserved : 1; -+ u32 dec_clkgate_e : 1; -+ u32 dec_e_strmd_clkgate_dis : 1; -+ u32 reserved0 : 1; -+ -+ u32 dec_irq_dis : 1; -+ u32 dec_timeout_e : 1; -+ u32 buf_empty_en : 1; -+ u32 reserved1 : 3; -+ -+ u32 dec_e_rewrite_valid : 1; -+ u32 reserved2 : 9; -+ u32 softrst_en_p : 1; -+ u32 force_softreset_valid : 1; -+ u32 reserved3 : 2; -+ u32 pix_range_detection_e : 1; -+ u32 reserved4 : 7; -+ } reg011; -+ -+ struct rkvdec2_sencodary_en { -+ u32 wr_ddr_align_en : 1; -+ u32 colmv_compress_en : 1; -+ u32 fbc_e : 1; -+ u32 reserved0 : 1; -+ -+ u32 buspr_slot_disable : 1; -+ u32 error_info_en : 1; -+ u32 info_collect_en : 1; -+ u32 wait_reset_en : 1; -+ -+ u32 scanlist_addr_valid_en : 1; -+ u32 scale_down_en : 1; -+ u32 error_cfg_wr_disable : 1; -+ u32 reserved1 : 21; -+ } reg012; -+ -+ struct rkvdec2_en_mode_set { -+ u32 timeout_mode : 1; -+ u32 req_timeout_rst_sel : 1; -+ u32 reserved0 : 1; -+ u32 dec_commonirq_mode : 1; -+ u32 reserved1 : 2; -+ u32 stmerror_waitdecfifo_empty : 1; -+ u32 reserved2 : 2; -+ u32 h26x_streamd_error_mode : 1; -+ u32 reserved3 : 2; -+ u32 allow_not_wr_unref_bframe : 1; -+ u32 fbc_output_wr_disable : 1; -+ u32 reserved4 : 1; -+ u32 colmv_error_mode : 1; -+ -+ u32 reserved5 : 2; -+ u32 h26x_error_mode : 1; -+ u32 reserved6 : 2; -+ u32 ycacherd_prior : 1; -+ u32 reserved7 : 2; -+ u32 cur_pic_is_idr : 1; -+ u32 reserved8 : 1; -+ u32 right_auto_rst_disable : 1; -+ u32 frame_end_err_rst_flag : 1; -+ u32 rd_prior_mode : 1; -+ u32 rd_ctrl_prior_mode : 1; -+ u32 reserved9 : 1; -+ u32 filter_outbuf_mode : 1; -+ } reg013; -+ -+ struct rkvdec2_fbc_param_set { -+ u32 fbc_force_uncompress : 1; -+ -+ u32 reserved0 : 2; -+ u32 allow_16x8_cp_flag : 1; -+ u32 reserved1 : 2; -+ -+ u32 fbc_h264_exten_4or8_flag : 1; -+ u32 reserved2 : 25; -+ } reg014; -+ -+ struct rkvdec2_stream_param_set { -+ u32 rlc_mode_direct_write : 1; -+ u32 rlc_mode : 1; -+ u32 reserved0 : 3; -+ -+ u32 strm_start_bit : 7; -+ u32 reserved1 : 20; -+ } reg015; -+ -+ u32 stream_len; -+ -+ struct rkvdec2_slice_number { -+ u32 slice_num : 25; -+ u32 reserved : 7; -+ } reg017; -+ -+ struct rkvdec2_y_hor_stride { -+ u32 y_hor_virstride : 16; -+ u32 reserved : 16; -+ } reg018; -+ -+ struct rkvdec2_uv_hor_stride { -+ u32 uv_hor_virstride : 16; -+ u32 reserved : 16; -+ } reg019; -+ -+ struct rkvdec2_y_stride { -+ u32 y_virstride : 28; -+ u32 reserved : 4; -+ } reg020; -+ -+ struct rkvdec2_error_ctrl_set { -+ u32 inter_error_prc_mode : 1; -+ u32 error_intra_mode : 1; -+ u32 error_deb_en : 1; -+ u32 picidx_replace : 5; -+ u32 error_spread_e : 1; -+ u32 reserved0 : 3; -+ u32 error_inter_pred_cross_slice : 1; -+ u32 reserved1 : 11; -+ u32 roi_error_ctu_cal_en : 1; -+ u32 reserved2 : 7; -+ } reg021; -+ -+ struct rkvdec2_err_roi_ctu_offset_start { -+ u32 roi_x_ctu_offset_st : 12; -+ u32 reserved0 : 4; -+ u32 roi_y_ctu_offset_st : 12; -+ u32 reserved1 : 4; -+ } reg022; -+ -+ struct rkvdec2_err_roi_ctu_offset_end { -+ u32 roi_x_ctu_offset_end : 12; -+ u32 reserved0 : 4; -+ u32 roi_y_ctu_offset_end : 12; -+ u32 reserved1 : 4; -+ } reg023; -+ -+ struct rkvdec2_cabac_error_en_lowbits { -+ u32 cabac_err_en_lowbits : 32; -+ } reg024; -+ -+ struct rkvdec2_cabac_error_en_highbits { -+ u32 cabac_err_en_highbits : 30; -+ u32 reserved : 2; -+ } reg025; -+ -+ struct rkvdec2_block_gating_en { -+ u32 swreg_block_gating_e : 20; -+ u32 reserved : 11; -+ u32 reg_cfg_gating_en : 1; -+ } reg026; -+ -+ struct SW027_CORE_SAFE_PIXELS { -+ u32 core_safe_x_pixels : 16; -+ u32 core_safe_y_pixels : 16; -+ } reg027; -+ -+ struct rkvdec2_multiply_core_ctrl { -+ u32 swreg_vp9_wr_prob_idx : 3; -+ u32 reserved0 : 1; -+ u32 swreg_vp9_rd_prob_idx : 3; -+ u32 reserved1 : 1; -+ -+ u32 swreg_ref_req_advance_flag : 1; -+ u32 sw_colmv_req_advance_flag : 1; -+ u32 sw_poc_only_highbit_flag : 1; -+ u32 sw_poc_arb_flag : 1; -+ -+ u32 reserved2 : 4; -+ u32 sw_film_idx : 10; -+ u32 reserved3 : 2; -+ u32 sw_pu_req_mismatch_dis : 1; -+ u32 sw_colmv_req_mismatch_dis : 1; -+ u32 reserved4 : 2; -+ } reg028; -+ -+ struct SW029_SCALE_DOWN_CTRL { -+ u32 scale_down_hor_ratio : 2; -+ u32 reserved0 : 6; -+ u32 scale_down_vrz_ratio : 2; -+ u32 reserved1 : 22; -+ } reg029; -+ -+ struct SW032_Y_SCALE_DOWN_TILE8x8_HOR_STRIDE { -+ u32 y_scale_down_hor_stride : 20; -+ u32 reserved0 : 12; -+ } reg030; -+ -+ struct SW031_UV_SCALE_DOWN_TILE8x8_HOR_STRIDE { -+ u32 uv_scale_down_hor_stride : 20; -+ u32 reserved0 : 12; -+ } reg031; -+ -+ u32 timeout_threshold; -+} __packed; -+ -+/* base: OFFSET_COMMON_ADDR_REGS */ -+struct rkvdec2_regs_common_addr { -+ u32 rlc_base; -+ u32 rlcwrite_base; -+ u32 decout_base; -+ u32 colmv_cur_base; -+ u32 error_ref_base; -+ u32 rcb_base[10]; -+} __packed; -+ -+/* base: OFFSET_CODEC_PARAMS_REGS */ -+struct rkvdec2_regs_h264_params { -+ struct rkvdec2_h26x_set { -+ u32 h26x_frame_orslice : 1; -+ u32 h26x_rps_mode : 1; -+ u32 h26x_stream_mode : 1; -+ u32 h26x_stream_lastpacket : 1; -+ u32 h264_firstslice_flag : 1; -+ u32 reserved : 27; -+ } reg064; -+ -+ u32 cur_top_poc; -+ u32 cur_bot_poc; -+ u32 ref_pocs[32]; -+ -+ struct rkvdec2_h264_info { -+ struct rkvdec2_h264_ref_info { -+ u32 ref_field : 1; -+ u32 ref_topfield_used : 1; -+ u32 ref_botfield_used : 1; -+ u32 ref_colmv_use_flag : 1; -+ u32 ref_reserved : 4; -+ } __packed ref_info[4]; -+ } __packed ref_info_regs[4]; -+ -+ u32 reserved_103_111[9]; -+ -+ struct rkvdec2_error_ref_info { -+ u32 avs2_ref_error_field : 1; -+ u32 avs2_ref_error_topfield : 1; -+ u32 ref_error_topfield_used : 1; -+ u32 ref_error_botfield_used : 1; -+ u32 reserved : 28; -+ } reg112; -+} __packed; -+ -+/* base: OFFSET_CODEC_ADDR_REGS */ -+struct rkvdec2_regs_h264_addr { -+ u32 reserved_160; -+ u32 pps_base; -+ u32 reserved_162; -+ u32 rps_base; -+ u32 ref_base[16]; -+ u32 scanlist_addr; -+ u32 colmv_base[16]; -+ u32 cabactbl_base; -+} __packed; -+ -+struct rkvdec2_regs_h264_highpoc { -+ struct rkvdec2_ref_poc_highbit { -+ u32 ref0_poc_highbit : 4; -+ u32 ref1_poc_highbit : 4; -+ u32 ref2_poc_highbit : 4; -+ u32 ref3_poc_highbit : 4; -+ u32 ref4_poc_highbit : 4; -+ u32 ref5_poc_highbit : 4; -+ u32 ref6_poc_highbit : 4; -+ u32 ref7_poc_highbit : 4; -+ } reg200[4]; -+ struct rkvdec2_cur_poc_highbit { -+ u32 cur_poc_highbit : 4; -+ u32 reserved : 28; -+ } reg204; -+} __packed; -+ -+struct rkvdec2_regs_h264 { -+ struct rkvdec2_regs_common common; -+ struct rkvdec2_regs_h264_params h264_param; -+ struct rkvdec2_regs_common_addr common_addr; -+ struct rkvdec2_regs_h264_addr h264_addr; -+ struct rkvdec2_regs_h264_highpoc h264_highpoc; -+} __packed; -+ -+#endif /* __RKVDEC_REGS_H__ */ -diff --git a/drivers/media/platform/rockchip/rkvdec2/rkvdec2.c b/drivers/media/platform/rockchip/rkvdec2/rkvdec2.c -new file mode 100644 -index 000000000000..852e88fc0ea1 ---- /dev/null -+++ b/drivers/media/platform/rockchip/rkvdec2/rkvdec2.c -@@ -0,0 +1,1263 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Rockchip Video Decoder 2 driver -+ * -+ * Copyright (C) 2024 Collabora, Ltd. -+ * Detlev Casanova <detlev.casanova@collabora.com> -+ * -+ * Based on rkvdec driver by Boris Brezillon <boris.brezillon@collabora.com> -+ */ -+ -+#include <linux/clk.h> -+#include <linux/genalloc.h> -+#include <linux/interrupt.h> -+#include <linux/iommu.h> -+#include <linux/module.h> -+#include <linux/of.h> -+#include <linux/platform_device.h> -+#include <linux/pm.h> -+#include <linux/pm_runtime.h> -+#include <linux/slab.h> -+#include <linux/videodev2.h> -+#include <linux/workqueue.h> -+#include <media/v4l2-event.h> -+#include <media/v4l2-mem2mem.h> -+#include <media/videobuf2-core.h> -+#include <media/videobuf2-vmalloc.h> -+ -+#include "rkvdec2.h" -+ -+static int rkvdec2_try_ctrl(struct v4l2_ctrl *ctrl) -+{ -+ struct rkvdec2_ctx *ctx = container_of(ctrl->handler, struct rkvdec2_ctx, ctrl_hdl); -+ const struct rkvdec2_coded_fmt_desc *desc = ctx->coded_fmt_desc; -+ -+ if (desc->ops->try_ctrl) -+ return desc->ops->try_ctrl(ctx, ctrl); -+ -+ return 0; -+} -+ -+static const struct v4l2_ctrl_ops rkvdec2_ctrl_ops = { -+ .try_ctrl = rkvdec2_try_ctrl, -+}; -+ -+static const struct rkvdec2_ctrl_desc rkvdec2_h264_ctrl_descs[] = { -+ { -+ .cfg.id = V4L2_CID_STATELESS_H264_DECODE_PARAMS, -+ }, -+ { -+ .cfg.id = V4L2_CID_STATELESS_H264_SPS, -+ .cfg.ops = &rkvdec2_ctrl_ops, -+ }, -+ { -+ .cfg.id = V4L2_CID_STATELESS_H264_PPS, -+ }, -+ { -+ .cfg.id = V4L2_CID_STATELESS_H264_SCALING_MATRIX, -+ }, -+ { -+ .cfg.id = V4L2_CID_STATELESS_H264_DECODE_MODE, -+ .cfg.min = V4L2_STATELESS_H264_DECODE_MODE_FRAME_BASED, -+ .cfg.max = V4L2_STATELESS_H264_DECODE_MODE_FRAME_BASED, -+ .cfg.def = V4L2_STATELESS_H264_DECODE_MODE_FRAME_BASED, -+ }, -+ { -+ .cfg.id = V4L2_CID_STATELESS_H264_START_CODE, -+ .cfg.min = V4L2_STATELESS_H264_START_CODE_ANNEX_B, -+ .cfg.def = V4L2_STATELESS_H264_START_CODE_ANNEX_B, -+ .cfg.max = V4L2_STATELESS_H264_START_CODE_ANNEX_B, -+ }, -+ { -+ .cfg.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE, -+ .cfg.min = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE, -+ .cfg.max = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH, -+ .cfg.menu_skip_mask = -+ BIT(V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED), -+ .cfg.def = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN, -+ }, -+ { -+ .cfg.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL, -+ .cfg.min = V4L2_MPEG_VIDEO_H264_LEVEL_1_0, -+ .cfg.max = V4L2_MPEG_VIDEO_H264_LEVEL_6_1, -+ }, -+}; -+ -+static const struct rkvdec2_ctrls rkvdec2_h264_ctrls = { -+ .ctrls = rkvdec2_h264_ctrl_descs, -+ .num_ctrls = ARRAY_SIZE(rkvdec2_h264_ctrl_descs), -+}; -+ -+static const u32 rkvdec2_h264_decoded_fmts[] = { -+ V4L2_PIX_FMT_NV12 -+}; -+ -+static const struct rkvdec2_coded_fmt_desc rkvdec2_coded_fmts[] = { -+ { -+ .fourcc = V4L2_PIX_FMT_H264_SLICE, -+ .frmsize = { -+ .min_width = 16, -+ .max_width = 65520, -+ .step_width = 16, -+ .min_height = 16, -+ .max_height = 65520, -+ .step_height = 16, -+ }, -+ .ctrls = &rkvdec2_h264_ctrls, -+ .ops = &rkvdec2_h264_fmt_ops, -+ .num_decoded_fmts = ARRAY_SIZE(rkvdec2_h264_decoded_fmts), -+ .decoded_fmts = rkvdec2_h264_decoded_fmts, -+ .subsystem_flags = VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF, -+ }, -+}; -+ -+enum rcb_axis { -+ PIC_WIDTH = 0, -+ PIC_HEIGHT = 1 -+}; -+ -+struct rcb_size_info { -+ u8 multiplier; -+ enum rcb_axis axis; -+}; -+ -+static struct rcb_size_info rcb_sizes[] = { -+ {6, PIC_WIDTH}, // intrar -+ {1, PIC_WIDTH}, // transdr (Is actually 0.4*pic_width) -+ {1, PIC_HEIGHT}, // transdc (Is actually 0.1*pic_height) -+ {3, PIC_WIDTH}, // streamdr -+ {6, PIC_WIDTH}, // interr -+ {3, PIC_HEIGHT}, // interc -+ {22, PIC_WIDTH}, // dblkr -+ {6, PIC_WIDTH}, // saor -+ {11, PIC_WIDTH}, // fbcr -+ {67, PIC_HEIGHT}, // filtc col -+}; -+ -+#define RCB_SIZE(n,w,h) (rcb_sizes[(n)].multiplier * (rcb_sizes[(n)].axis ? (h) : (w))) -+ -+static const struct rkvdec2_coded_fmt_desc * -+rkvdec2_find_coded_fmt_desc(u32 fourcc) -+{ -+ unsigned int i; -+ -+ for (i = 0; i < ARRAY_SIZE(rkvdec2_coded_fmts); i++) { -+ if (rkvdec2_coded_fmts[i].fourcc == fourcc) -+ return &rkvdec2_coded_fmts[i]; -+ } -+ -+ return NULL; -+} -+ -+static void rkvdec2_reset_fmt(struct rkvdec2_ctx *ctx, struct v4l2_format *f, -+ u32 fourcc) -+{ -+ memset(f, 0, sizeof(*f)); -+ f->fmt.pix_mp.pixelformat = fourcc; -+ f->fmt.pix_mp.field = V4L2_FIELD_NONE; -+ f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709; -+ f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; -+ f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT; -+ f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT; -+} -+ -+static void rkvdec2_reset_coded_fmt(struct rkvdec2_ctx *ctx) -+{ -+ struct v4l2_format *f = &ctx->coded_fmt; -+ -+ ctx->coded_fmt_desc = &rkvdec2_coded_fmts[0]; -+ rkvdec2_reset_fmt(ctx, f, ctx->coded_fmt_desc->fourcc); -+ -+ f->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; -+ f->fmt.pix_mp.width = ctx->coded_fmt_desc->frmsize.min_width; -+ f->fmt.pix_mp.height = ctx->coded_fmt_desc->frmsize.min_height; -+ -+ if (ctx->coded_fmt_desc->ops->adjust_fmt) -+ ctx->coded_fmt_desc->ops->adjust_fmt(ctx, f); -+} -+ -+static void rkvdec2_reset_decoded_fmt(struct rkvdec2_ctx *ctx) -+{ -+ struct v4l2_format *f = &ctx->decoded_fmt; -+ -+ rkvdec2_reset_fmt(ctx, f, ctx->coded_fmt_desc->decoded_fmts[0]); -+ f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; -+ v4l2_fill_pixfmt_mp(&f->fmt.pix_mp, -+ ctx->coded_fmt_desc->decoded_fmts[0], -+ ctx->coded_fmt.fmt.pix_mp.width, -+ ctx->coded_fmt.fmt.pix_mp.height); -+ -+ ctx->colmv_offset = f->fmt.pix_mp.plane_fmt[0].sizeimage; -+ -+ f->fmt.pix_mp.plane_fmt[0].sizeimage += 128 * -+ DIV_ROUND_UP(f->fmt.pix_mp.width, 16) * -+ DIV_ROUND_UP(f->fmt.pix_mp.height, 16); -+} -+ -+static int rkvdec2_enum_framesizes(struct file *file, void *priv, -+ struct v4l2_frmsizeenum *fsize) -+{ -+ const struct rkvdec2_coded_fmt_desc *desc; -+ -+ if (fsize->index != 0) -+ return -EINVAL; -+ -+ desc = rkvdec2_find_coded_fmt_desc(fsize->pixel_format); -+ if (!desc) -+ return -EINVAL; -+ -+ fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS; -+ -+ fsize->stepwise.min_height = 1; -+ fsize->stepwise.min_width = 1; -+ fsize->stepwise.step_height = 1; -+ fsize->stepwise.step_width = 1; -+ fsize->stepwise.max_height = desc->frmsize.max_height; -+ fsize->stepwise.max_width = desc->frmsize.max_width; -+ -+ return 0; -+} -+ -+static int rkvdec2_querycap(struct file *file, void *priv, -+ struct v4l2_capability *cap) -+{ -+ struct rkvdec2_dev *rkvdec = video_drvdata(file); -+ struct video_device *vdev = video_devdata(file); -+ -+ strscpy(cap->driver, rkvdec->dev->driver->name, -+ sizeof(cap->driver)); -+ strscpy(cap->card, vdev->name, sizeof(cap->card)); -+ snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", -+ rkvdec->dev->driver->name); -+ return 0; -+} -+ -+static int rkvdec2_try_capture_fmt(struct file *file, void *priv, -+ struct v4l2_format *f) -+{ -+ struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; -+ struct rkvdec2_ctx *ctx = fh_to_rkvdec2_ctx(priv); -+ const struct rkvdec2_coded_fmt_desc *coded_desc; -+ unsigned int i; -+ -+ /* -+ * The codec context should point to a coded format desc, if the format -+ * on the coded end has not been set yet, it should point to the -+ * default value. -+ */ -+ coded_desc = ctx->coded_fmt_desc; -+ if (WARN_ON(!coded_desc)) -+ return -EINVAL; -+ -+ for (i = 0; i < coded_desc->num_decoded_fmts; i++) { -+ if (coded_desc->decoded_fmts[i] == pix_mp->pixelformat) -+ break; -+ } -+ -+ if (i == coded_desc->num_decoded_fmts) -+ pix_mp->pixelformat = coded_desc->decoded_fmts[0]; -+ -+ /* Always apply the frmsize constraint of the coded end. */ -+ pix_mp->width = max(pix_mp->width, ctx->coded_fmt.fmt.pix_mp.width); -+ pix_mp->height = max(pix_mp->height, ctx->coded_fmt.fmt.pix_mp.height); -+ v4l2_apply_frmsize_constraints(&pix_mp->width, -+ &pix_mp->height, -+ &coded_desc->frmsize); -+ -+ v4l2_fill_pixfmt_mp(pix_mp, pix_mp->pixelformat, -+ pix_mp->width, pix_mp->height); -+ -+ pix_mp->plane_fmt[0].sizeimage += -+ 128 * -+ DIV_ROUND_UP(pix_mp->width, 16) * -+ DIV_ROUND_UP(pix_mp->height, 16); -+ -+ pix_mp->field = V4L2_FIELD_NONE; -+ -+ return 0; -+} -+ -+static int rkvdec2_try_output_fmt(struct file *file, void *priv, -+ struct v4l2_format *f) -+{ -+ struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; -+ struct rkvdec2_ctx *ctx = fh_to_rkvdec2_ctx(priv); -+ const struct rkvdec2_coded_fmt_desc *desc; -+ -+ desc = rkvdec2_find_coded_fmt_desc(pix_mp->pixelformat); -+ if (!desc) { -+ pix_mp->pixelformat = rkvdec2_coded_fmts[0].fourcc; -+ desc = &rkvdec2_coded_fmts[0]; -+ } -+ -+ v4l2_apply_frmsize_constraints(&pix_mp->width, -+ &pix_mp->height, -+ &desc->frmsize); -+ -+ pix_mp->field = V4L2_FIELD_NONE; -+ /* All coded formats are considered single planar for now. */ -+ pix_mp->num_planes = 1; -+ -+ if (desc->ops->adjust_fmt) { -+ int ret; -+ -+ ret = desc->ops->adjust_fmt(ctx, f); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int rkvdec2_s_capture_fmt(struct file *file, void *priv, -+ struct v4l2_format *f) -+{ -+ struct rkvdec2_ctx *ctx = fh_to_rkvdec2_ctx(priv); -+ struct vb2_queue *vq; -+ int ret; -+ -+ /* Change not allowed if queue is busy */ -+ vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, -+ V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); -+ if (vb2_is_busy(vq)) -+ return -EBUSY; -+ -+ ret = rkvdec2_try_capture_fmt(file, priv, f); -+ if (ret) -+ return ret; -+ -+ ctx->decoded_fmt = *f; -+ return 0; -+} -+ -+static int rkvdec2_s_output_fmt(struct file *file, void *priv, -+ struct v4l2_format *f) -+{ -+ struct rkvdec2_ctx *ctx = fh_to_rkvdec2_ctx(priv); -+ struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx; -+ const struct rkvdec2_coded_fmt_desc *desc; -+ struct v4l2_format *cap_fmt; -+ struct vb2_queue *peer_vq, *vq; -+ int ret; -+ -+ /* -+ * In order to support dynamic resolution change, the decoder admits -+ * a resolution change, as long as the pixelformat remains. Can't be -+ * done if streaming. -+ */ -+ vq = v4l2_m2m_get_vq(m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); -+ if (vb2_is_streaming(vq) || -+ (vb2_is_busy(vq) && -+ f->fmt.pix_mp.pixelformat != ctx->coded_fmt.fmt.pix_mp.pixelformat)) -+ return -EBUSY; -+ -+ /* -+ * Since format change on the OUTPUT queue will reset the CAPTURE -+ * queue, we can't allow doing so when the CAPTURE queue has buffers -+ * allocated. -+ */ -+ peer_vq = v4l2_m2m_get_vq(m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); -+ if (vb2_is_busy(peer_vq)) -+ return -EBUSY; -+ -+ ret = rkvdec2_try_output_fmt(file, priv, f); -+ if (ret) -+ return ret; -+ -+ desc = rkvdec2_find_coded_fmt_desc(f->fmt.pix_mp.pixelformat); -+ if (!desc) -+ return -EINVAL; -+ ctx->coded_fmt_desc = desc; -+ ctx->coded_fmt = *f; -+ -+ /* -+ * Current decoded format might have become invalid with newly -+ * selected codec, so reset it to default just to be safe and -+ * keep internal driver state sane. User is mandated to set -+ * the decoded format again after we return, so we don't need -+ * anything smarter. -+ * -+ * Note that this will propagate any size changes to the decoded format. -+ */ -+ rkvdec2_reset_decoded_fmt(ctx); -+ -+ /* Propagate colorspace information to capture. */ -+ cap_fmt = &ctx->decoded_fmt; -+ cap_fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace; -+ cap_fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func; -+ cap_fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc; -+ cap_fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization; -+ -+ /* Enable format specific queue features */ -+ vq->subsystem_flags |= desc->subsystem_flags; -+ -+ return 0; -+} -+ -+static int rkvdec2_g_output_fmt(struct file *file, void *priv, -+ struct v4l2_format *f) -+{ -+ struct rkvdec2_ctx *ctx = fh_to_rkvdec2_ctx(priv); -+ -+ *f = ctx->coded_fmt; -+ return 0; -+} -+ -+static int rkvdec2_g_capture_fmt(struct file *file, void *priv, -+ struct v4l2_format *f) -+{ -+ struct rkvdec2_ctx *ctx = fh_to_rkvdec2_ctx(priv); -+ -+ *f = ctx->decoded_fmt; -+ return 0; -+} -+ -+static int rkvdec2_enum_output_fmt(struct file *file, void *priv, -+ struct v4l2_fmtdesc *f) -+{ -+ if (f->index >= ARRAY_SIZE(rkvdec2_coded_fmts)) -+ return -EINVAL; -+ -+ f->pixelformat = rkvdec2_coded_fmts[f->index].fourcc; -+ return 0; -+} -+ -+static int rkvdec2_enum_capture_fmt(struct file *file, void *priv, -+ struct v4l2_fmtdesc *f) -+{ -+ struct rkvdec2_ctx *ctx = fh_to_rkvdec2_ctx(priv); -+ -+ if (WARN_ON(!ctx->coded_fmt_desc)) -+ return -EINVAL; -+ -+ if (f->index >= ctx->coded_fmt_desc->num_decoded_fmts) -+ return -EINVAL; -+ -+ f->pixelformat = ctx->coded_fmt_desc->decoded_fmts[f->index]; -+ return 0; -+} -+ -+static const struct v4l2_ioctl_ops rkvdec2_ioctl_ops = { -+ .vidioc_querycap = rkvdec2_querycap, -+ .vidioc_enum_framesizes = rkvdec2_enum_framesizes, -+ -+ .vidioc_try_fmt_vid_cap_mplane = rkvdec2_try_capture_fmt, -+ .vidioc_try_fmt_vid_out_mplane = rkvdec2_try_output_fmt, -+ .vidioc_s_fmt_vid_out_mplane = rkvdec2_s_output_fmt, -+ .vidioc_s_fmt_vid_cap_mplane = rkvdec2_s_capture_fmt, -+ .vidioc_g_fmt_vid_out_mplane = rkvdec2_g_output_fmt, -+ .vidioc_g_fmt_vid_cap_mplane = rkvdec2_g_capture_fmt, -+ .vidioc_enum_fmt_vid_out = rkvdec2_enum_output_fmt, -+ .vidioc_enum_fmt_vid_cap = rkvdec2_enum_capture_fmt, -+ -+ .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, -+ .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, -+ .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, -+ .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, -+ .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, -+ .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, -+ .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, -+ -+ .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, -+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe, -+ -+ .vidioc_streamon = v4l2_m2m_ioctl_streamon, -+ .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, -+ -+ .vidioc_decoder_cmd = v4l2_m2m_ioctl_stateless_decoder_cmd, -+ .vidioc_try_decoder_cmd = v4l2_m2m_ioctl_stateless_try_decoder_cmd, -+}; -+ -+static int rkvdec2_queue_setup(struct vb2_queue *vq, unsigned int *num_buffers, -+ unsigned int *num_planes, unsigned int sizes[], -+ struct device *alloc_devs[]) -+{ -+ struct rkvdec2_ctx *ctx = vb2_get_drv_priv(vq); -+ struct v4l2_format *f; -+ unsigned int i; -+ -+ if (V4L2_TYPE_IS_OUTPUT(vq->type)) -+ f = &ctx->coded_fmt; -+ else -+ f = &ctx->decoded_fmt; -+ -+ if (*num_planes) { -+ if (*num_planes != f->fmt.pix_mp.num_planes) -+ return -EINVAL; -+ -+ for (i = 0; i < f->fmt.pix_mp.num_planes; i++) { -+ if (sizes[i] < f->fmt.pix_mp.plane_fmt[i].sizeimage) -+ return -EINVAL; -+ } -+ } else { -+ *num_planes = f->fmt.pix_mp.num_planes; -+ for (i = 0; i < f->fmt.pix_mp.num_planes; i++) -+ sizes[i] = f->fmt.pix_mp.plane_fmt[i].sizeimage; -+ } -+ -+ return 0; -+} -+ -+static int rkvdec2_buf_prepare(struct vb2_buffer *vb) -+{ -+ struct vb2_queue *vq = vb->vb2_queue; -+ struct rkvdec2_ctx *ctx = vb2_get_drv_priv(vq); -+ struct v4l2_format *f; -+ unsigned int i; -+ -+ if (V4L2_TYPE_IS_OUTPUT(vq->type)) -+ f = &ctx->coded_fmt; -+ else -+ f = &ctx->decoded_fmt; -+ -+ for (i = 0; i < f->fmt.pix_mp.num_planes; ++i) { -+ u32 sizeimage = f->fmt.pix_mp.plane_fmt[i].sizeimage; -+ -+ if (vb2_plane_size(vb, i) < sizeimage) -+ return -EINVAL; -+ } -+ -+ /* -+ * Buffer's bytesused must be written by driver for CAPTURE buffers. -+ * (for OUTPUT buffers, if userspace passes 0 bytesused, v4l2-core sets -+ * it to buffer length). -+ */ -+ if (V4L2_TYPE_IS_CAPTURE(vq->type)) -+ vb2_set_plane_payload(vb, 0, f->fmt.pix_mp.plane_fmt[0].sizeimage); -+ -+ return 0; -+} -+ -+static void rkvdec2_buf_queue(struct vb2_buffer *vb) -+{ -+ struct rkvdec2_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); -+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); -+ -+ v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); -+} -+ -+static int rkvdec2_buf_out_validate(struct vb2_buffer *vb) -+{ -+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); -+ -+ vbuf->field = V4L2_FIELD_NONE; -+ return 0; -+} -+ -+static void rkvdec2_buf_request_complete(struct vb2_buffer *vb) -+{ -+ struct rkvdec2_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); -+ -+ v4l2_ctrl_request_complete(vb->req_obj.req, &ctx->ctrl_hdl); -+} -+ -+static void rkvdec2_free_rcb(struct rkvdec2_ctx *ctx) -+{ -+ u32 width, height; -+ int i; -+ -+ width = ctx->decoded_fmt.fmt.pix_mp.width; -+ height = ctx->decoded_fmt.fmt.pix_mp.height; -+ -+ for (i = 0; i < RKVDEC2_RCB_COUNT; i++) { -+ size_t rcb_size = RCB_SIZE(i, width, height); -+ -+ if (!ctx->rcb_bufs[i].cpu) -+ continue; -+ -+ switch (ctx->rcb_bufs[i].type) { -+ case RKVDEC2_ALLOC_SRAM: -+ gen_pool_free(ctx->dev->sram_pool, -+ (unsigned long)ctx->rcb_bufs[i].cpu, -+ rcb_size); -+ break; -+ case RKVDEC2_ALLOC_DMA: -+ dma_free_coherent(ctx->dev->dev, -+ rcb_size, -+ ctx->rcb_bufs[i].cpu, -+ ctx->rcb_bufs[i].dma); -+ break; -+ } -+ } -+} -+ -+static int rkvdec2_allocate_rcb(struct rkvdec2_ctx *ctx) -+{ -+ int ret, i; -+ u32 width, height; -+ -+ memset(ctx->rcb_bufs, 0, sizeof(*ctx->rcb_bufs)); -+ -+ width = ctx->decoded_fmt.fmt.pix_mp.width; -+ height = ctx->decoded_fmt.fmt.pix_mp.height; -+ -+ for (i = 0; i < RKVDEC2_RCB_COUNT; i++) { -+ void *cpu = NULL; -+ dma_addr_t dma; -+ size_t rcb_size = RCB_SIZE(i, width, height); -+ enum rkvdec2_alloc_type alloc_type = RKVDEC2_ALLOC_SRAM; -+ -+ if (ctx->dev->sram_pool) { -+ cpu = gen_pool_dma_zalloc_align(ctx->dev->sram_pool, -+ rcb_size, -+ &dma, -+ 64); -+ } -+ -+ /* Fallback to RAM */ -+ if (!cpu) { -+ cpu = dma_alloc_coherent(ctx->dev->dev, -+ rcb_size, -+ &dma, -+ GFP_KERNEL); -+ alloc_type = RKVDEC2_ALLOC_DMA; -+ } -+ -+ if (!cpu) { -+ ret = -ENOMEM; -+ goto err_alloc; -+ } -+ -+ ctx->rcb_bufs[i].cpu = cpu; -+ ctx->rcb_bufs[i].dma = dma; -+ ctx->rcb_bufs[i].size = rcb_size; -+ ctx->rcb_bufs[i].type = alloc_type; -+ } -+ -+ return 0; -+ -+err_alloc: -+ rkvdec2_free_rcb(ctx); -+ -+ return ret; -+} -+ -+static int rkvdec2_start_streaming(struct vb2_queue *q, unsigned int count) -+{ -+ struct rkvdec2_ctx *ctx = vb2_get_drv_priv(q); -+ const struct rkvdec2_coded_fmt_desc *desc; -+ int ret; -+ -+ if (V4L2_TYPE_IS_CAPTURE(q->type)) -+ return 0; -+ -+ desc = ctx->coded_fmt_desc; -+ if (WARN_ON(!desc)) -+ return -EINVAL; -+ -+ ret = rkvdec2_allocate_rcb(ctx); -+ if (ret) -+ return ret; -+ -+ if (desc->ops->start) { -+ ret = desc->ops->start(ctx); -+ if (ret) -+ goto err_ops_start; -+ } -+ -+ return 0; -+ -+err_ops_start: -+ rkvdec2_free_rcb(ctx); -+ -+ return ret; -+} -+ -+static void rkvdec2_queue_cleanup(struct vb2_queue *vq, u32 state) -+{ -+ struct rkvdec2_ctx *ctx = vb2_get_drv_priv(vq); -+ -+ while (true) { -+ struct vb2_v4l2_buffer *vbuf; -+ -+ if (V4L2_TYPE_IS_OUTPUT(vq->type)) -+ vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); -+ else -+ vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); -+ -+ if (!vbuf) -+ break; -+ -+ v4l2_ctrl_request_complete(vbuf->vb2_buf.req_obj.req, -+ &ctx->ctrl_hdl); -+ v4l2_m2m_buf_done(vbuf, state); -+ } -+} -+ -+static void rkvdec2_stop_streaming(struct vb2_queue *q) -+{ -+ struct rkvdec2_ctx *ctx = vb2_get_drv_priv(q); -+ -+ if (V4L2_TYPE_IS_OUTPUT(q->type)) { -+ const struct rkvdec2_coded_fmt_desc *desc = ctx->coded_fmt_desc; -+ -+ if (WARN_ON(!desc)) -+ return; -+ -+ if (desc->ops->stop) -+ desc->ops->stop(ctx); -+ -+ rkvdec2_free_rcb(ctx); -+ } -+ -+ rkvdec2_queue_cleanup(q, VB2_BUF_STATE_ERROR); -+} -+ -+static const struct vb2_ops rkvdec2_queue_ops = { -+ .queue_setup = rkvdec2_queue_setup, -+ .buf_prepare = rkvdec2_buf_prepare, -+ .buf_queue = rkvdec2_buf_queue, -+ .buf_out_validate = rkvdec2_buf_out_validate, -+ .buf_request_complete = rkvdec2_buf_request_complete, -+ .start_streaming = rkvdec2_start_streaming, -+ .stop_streaming = rkvdec2_stop_streaming, -+ .wait_prepare = vb2_ops_wait_prepare, -+ .wait_finish = vb2_ops_wait_finish, -+}; -+ -+static int rkvdec2_request_validate(struct media_request *req) -+{ -+ unsigned int count; -+ -+ count = vb2_request_buffer_cnt(req); -+ if (!count) -+ return -ENOENT; -+ else if (count > 1) -+ return -EINVAL; -+ -+ return vb2_request_validate(req); -+} -+ -+static const struct media_device_ops rkvdec2_media_ops = { -+ .req_validate = rkvdec2_request_validate, -+ .req_queue = v4l2_m2m_request_queue, -+}; -+ -+static void rkvdec2_job_finish_no_pm(struct rkvdec2_ctx *ctx, -+ enum vb2_buffer_state result) -+{ -+ if (ctx->coded_fmt_desc->ops->done) { -+ struct vb2_v4l2_buffer *src_buf, *dst_buf; -+ -+ src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); -+ dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); -+ ctx->coded_fmt_desc->ops->done(ctx, src_buf, dst_buf, result); -+ } -+ -+ v4l2_m2m_buf_done_and_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx, -+ result); -+} -+ -+static void rkvdec2_job_finish(struct rkvdec2_ctx *ctx, -+ enum vb2_buffer_state result) -+{ -+ struct rkvdec2_dev *rkvdec = ctx->dev; -+ -+ pm_runtime_mark_last_busy(rkvdec->dev); -+ pm_runtime_put_autosuspend(rkvdec->dev); -+ rkvdec2_job_finish_no_pm(ctx, result); -+} -+ -+void rkvdec2_run_preamble(struct rkvdec2_ctx *ctx, struct rkvdec2_run *run) -+{ -+ struct media_request *src_req; -+ -+ memset(run, 0, sizeof(*run)); -+ -+ run->bufs.src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); -+ run->bufs.dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); -+ -+ /* Apply request(s) controls if needed. */ -+ src_req = run->bufs.src->vb2_buf.req_obj.req; -+ if (src_req) -+ v4l2_ctrl_request_setup(src_req, &ctx->ctrl_hdl); -+ -+ v4l2_m2m_buf_copy_metadata(run->bufs.src, run->bufs.dst, true); -+} -+ -+void rkvdec2_run_postamble(struct rkvdec2_ctx *ctx, struct rkvdec2_run *run) -+{ -+ struct media_request *src_req = run->bufs.src->vb2_buf.req_obj.req; -+ -+ if (src_req) -+ v4l2_ctrl_request_complete(src_req, &ctx->ctrl_hdl); -+} -+ -+static void rkvdec2_device_run(void *priv) -+{ -+ struct rkvdec2_ctx *ctx = priv; -+ struct rkvdec2_dev *rkvdec = ctx->dev; -+ const struct rkvdec2_coded_fmt_desc *desc = ctx->coded_fmt_desc; -+ int ret; -+ -+ if (WARN_ON(!desc)) -+ return; -+ -+ ret = pm_runtime_resume_and_get(rkvdec->dev); -+ if (ret < 0) { -+ rkvdec2_job_finish_no_pm(ctx, VB2_BUF_STATE_ERROR); -+ return; -+ } -+ -+ ret = desc->ops->run(ctx); -+ if (ret) -+ rkvdec2_job_finish(ctx, VB2_BUF_STATE_ERROR); -+} -+ -+static const struct v4l2_m2m_ops rkvdec2_m2m_ops = { -+ .device_run = rkvdec2_device_run, -+}; -+ -+static int rkvdec2_queue_init(void *priv, -+ struct vb2_queue *src_vq, -+ struct vb2_queue *dst_vq) -+{ -+ struct rkvdec2_ctx *ctx = priv; -+ struct rkvdec2_dev *rkvdec = ctx->dev; -+ int ret; -+ -+ src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; -+ src_vq->io_modes = VB2_MMAP | VB2_DMABUF; -+ src_vq->drv_priv = ctx; -+ src_vq->ops = &rkvdec2_queue_ops; -+ src_vq->mem_ops = &vb2_dma_contig_memops; -+ -+ /* -+ * No CPU access on the queues, so no kernel mapping needed. -+ */ -+ src_vq->dma_attrs = DMA_ATTR_NO_KERNEL_MAPPING; -+ src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); -+ src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; -+ src_vq->lock = &rkvdec->vdev_lock; -+ src_vq->dev = rkvdec->v4l2_dev.dev; -+ src_vq->supports_requests = true; -+ src_vq->requires_requests = true; -+ -+ ret = vb2_queue_init(src_vq); -+ if (ret) -+ return ret; -+ -+ dst_vq->bidirectional = true; -+ dst_vq->mem_ops = &vb2_dma_contig_memops; -+ dst_vq->dma_attrs = DMA_ATTR_NO_KERNEL_MAPPING; -+ dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; -+ dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; -+ dst_vq->drv_priv = ctx; -+ dst_vq->ops = &rkvdec2_queue_ops; -+ dst_vq->buf_struct_size = sizeof(struct rkvdec2_decoded_buffer); -+ dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; -+ dst_vq->lock = &rkvdec->vdev_lock; -+ dst_vq->dev = rkvdec->v4l2_dev.dev; -+ -+ return vb2_queue_init(dst_vq); -+} -+ -+static int rkvdec2_add_ctrls(struct rkvdec2_ctx *ctx, -+ const struct rkvdec2_ctrls *ctrls) -+{ -+ unsigned int i; -+ -+ for (i = 0; i < ctrls->num_ctrls; i++) { -+ const struct v4l2_ctrl_config *cfg = &ctrls->ctrls[i].cfg; -+ -+ v4l2_ctrl_new_custom(&ctx->ctrl_hdl, cfg, ctx); -+ if (ctx->ctrl_hdl.error) -+ return ctx->ctrl_hdl.error; -+ } -+ -+ return 0; -+} -+ -+static int rkvdec2_init_ctrls(struct rkvdec2_ctx *ctx) -+{ -+ unsigned int i, nctrls = 0; -+ int ret; -+ -+ for (i = 0; i < ARRAY_SIZE(rkvdec2_coded_fmts); i++) -+ nctrls += rkvdec2_coded_fmts[i].ctrls->num_ctrls; -+ -+ v4l2_ctrl_handler_init(&ctx->ctrl_hdl, nctrls); -+ -+ for (i = 0; i < ARRAY_SIZE(rkvdec2_coded_fmts); i++) { -+ ret = rkvdec2_add_ctrls(ctx, rkvdec2_coded_fmts[i].ctrls); -+ if (ret) -+ goto err_free_handler; -+ } -+ -+ ret = v4l2_ctrl_handler_setup(&ctx->ctrl_hdl); -+ if (ret) -+ goto err_free_handler; -+ -+ ctx->fh.ctrl_handler = &ctx->ctrl_hdl; -+ return 0; -+ -+err_free_handler: -+ v4l2_ctrl_handler_free(&ctx->ctrl_hdl); -+ return ret; -+} -+ -+static int rkvdec2_open(struct file *filp) -+{ -+ struct rkvdec2_dev *rkvdec = video_drvdata(filp); -+ struct rkvdec2_ctx *ctx; -+ int ret; -+ -+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); -+ if (!ctx) -+ return -ENOMEM; -+ -+ ctx->dev = rkvdec; -+ rkvdec2_reset_coded_fmt(ctx); -+ rkvdec2_reset_decoded_fmt(ctx); -+ v4l2_fh_init(&ctx->fh, video_devdata(filp)); -+ -+ ret = rkvdec2_init_ctrls(ctx); -+ if (ret) -+ goto err_free_ctx; -+ -+ ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(rkvdec->m2m_dev, ctx, -+ rkvdec2_queue_init); -+ if (IS_ERR(ctx->fh.m2m_ctx)) { -+ ret = PTR_ERR(ctx->fh.m2m_ctx); -+ goto err_cleanup_ctrls; -+ } -+ -+ filp->private_data = &ctx->fh; -+ v4l2_fh_add(&ctx->fh); -+ -+ return 0; -+ -+err_cleanup_ctrls: -+ v4l2_ctrl_handler_free(&ctx->ctrl_hdl); -+ -+err_free_ctx: -+ kfree(ctx); -+ return ret; -+} -+ -+static int rkvdec2_release(struct file *filp) -+{ -+ struct rkvdec2_ctx *ctx = fh_to_rkvdec2_ctx(filp->private_data); -+ -+ v4l2_fh_del(&ctx->fh); -+ v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); -+ v4l2_ctrl_handler_free(&ctx->ctrl_hdl); -+ v4l2_fh_exit(&ctx->fh); -+ kfree(ctx); -+ -+ return 0; -+} -+ -+static const struct v4l2_file_operations rkvdec2_fops = { -+ .owner = THIS_MODULE, -+ .open = rkvdec2_open, -+ .release = rkvdec2_release, -+ .poll = v4l2_m2m_fop_poll, -+ .unlocked_ioctl = video_ioctl2, -+ .mmap = v4l2_m2m_fop_mmap, -+}; -+ -+static int rkvdec2_v4l2_init(struct rkvdec2_dev *rkvdec) -+{ -+ int ret; -+ -+ ret = v4l2_device_register(rkvdec->dev, &rkvdec->v4l2_dev); -+ if (ret) { -+ dev_err(rkvdec->dev, "Failed to register V4L2 device\n"); -+ return ret; -+ } -+ -+ rkvdec->m2m_dev = v4l2_m2m_init(&rkvdec2_m2m_ops); -+ if (IS_ERR(rkvdec->m2m_dev)) { -+ v4l2_err(&rkvdec->v4l2_dev, "Failed to init mem2mem device\n"); -+ ret = PTR_ERR(rkvdec->m2m_dev); -+ goto err_unregister_v4l2; -+ } -+ -+ rkvdec->mdev.dev = rkvdec->dev; -+ strscpy(rkvdec->mdev.model, "rkvdec2", sizeof(rkvdec->mdev.model)); -+ strscpy(rkvdec->mdev.bus_info, "platform:rkvdec2", -+ sizeof(rkvdec->mdev.bus_info)); -+ media_device_init(&rkvdec->mdev); -+ rkvdec->mdev.ops = &rkvdec2_media_ops; -+ rkvdec->v4l2_dev.mdev = &rkvdec->mdev; -+ -+ rkvdec->vdev.lock = &rkvdec->vdev_lock; -+ rkvdec->vdev.v4l2_dev = &rkvdec->v4l2_dev; -+ rkvdec->vdev.fops = &rkvdec2_fops; -+ rkvdec->vdev.release = video_device_release_empty; -+ rkvdec->vdev.vfl_dir = VFL_DIR_M2M; -+ rkvdec->vdev.device_caps = V4L2_CAP_STREAMING | -+ V4L2_CAP_VIDEO_M2M_MPLANE; -+ rkvdec->vdev.ioctl_ops = &rkvdec2_ioctl_ops; -+ video_set_drvdata(&rkvdec->vdev, rkvdec); -+ strscpy(rkvdec->vdev.name, "rkvdec2", sizeof(rkvdec->vdev.name)); -+ -+ ret = video_register_device(&rkvdec->vdev, VFL_TYPE_VIDEO, -1); -+ if (ret) { -+ v4l2_err(&rkvdec->v4l2_dev, "Failed to register video device\n"); -+ goto err_cleanup_mc; -+ } -+ -+ ret = v4l2_m2m_register_media_controller(rkvdec->m2m_dev, &rkvdec->vdev, -+ MEDIA_ENT_F_PROC_VIDEO_DECODER); -+ if (ret) { -+ v4l2_err(&rkvdec->v4l2_dev, -+ "Failed to initialize V4L2 M2M media controller\n"); -+ goto err_unregister_vdev; -+ } -+ -+ ret = media_device_register(&rkvdec->mdev); -+ if (ret) { -+ v4l2_err(&rkvdec->v4l2_dev, "Failed to register media device\n"); -+ goto err_unregister_mc; -+ } -+ -+ return 0; -+ -+err_unregister_mc: -+ v4l2_m2m_unregister_media_controller(rkvdec->m2m_dev); -+ -+err_unregister_vdev: -+ video_unregister_device(&rkvdec->vdev); -+ -+err_cleanup_mc: -+ media_device_cleanup(&rkvdec->mdev); -+ v4l2_m2m_release(rkvdec->m2m_dev); -+ -+err_unregister_v4l2: -+ v4l2_device_unregister(&rkvdec->v4l2_dev); -+ return ret; -+} -+ -+static void rkvdec2_v4l2_cleanup(struct rkvdec2_dev *rkvdec) -+{ -+ media_device_unregister(&rkvdec->mdev); -+ v4l2_m2m_unregister_media_controller(rkvdec->m2m_dev); -+ video_unregister_device(&rkvdec->vdev); -+ media_device_cleanup(&rkvdec->mdev); -+ v4l2_m2m_release(rkvdec->m2m_dev); -+ v4l2_device_unregister(&rkvdec->v4l2_dev); -+} -+ -+static irqreturn_t rkvdec2_irq_handler(int irq, void *priv) -+{ -+ struct rkvdec2_dev *rkvdec = priv; -+ enum vb2_buffer_state state; -+ u32 status; -+ -+ status = readl(rkvdec->regs + RKVDEC2_REG_STA_INT); -+ state = (status & STA_INT_DEC_RDY_STA) ? -+ VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR; -+ -+ /* Clear interrupt status */ -+ writel(0, rkvdec->regs + RKVDEC2_REG_STA_INT); -+ if (cancel_delayed_work(&rkvdec->watchdog_work)) { -+ struct rkvdec2_ctx *ctx; -+ -+ ctx = v4l2_m2m_get_curr_priv(rkvdec->m2m_dev); -+ rkvdec2_job_finish(ctx, state); -+ } -+ -+ return IRQ_HANDLED; -+} -+ -+static void rkvdec2_watchdog_func(struct work_struct *work) -+{ -+ struct rkvdec2_dev *rkvdec = container_of(to_delayed_work(work), struct rkvdec2_dev, -+ watchdog_work); -+ struct rkvdec2_ctx *ctx; -+ -+ ctx = v4l2_m2m_get_curr_priv(rkvdec->m2m_dev); -+ if (ctx) { -+ dev_err(rkvdec->dev, "Frame processing timed out!\n"); -+ writel(RKVDEC2_REG_DEC_IRQ_DISABLE, rkvdec->regs + RKVDEC2_REG_IMPORTANT_EN); -+ writel(0, rkvdec->regs + RKVDEC2_REG_DEC_E); -+ rkvdec2_job_finish(ctx, VB2_BUF_STATE_ERROR); -+ } -+} -+ -+static const struct of_device_id of_rkvdec2_match[] = { -+ { .compatible = "rockchip,rk3588-vdec" }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, of_rkvdec2_match); -+ -+static const char * const rkvdec2_clk_names[] = { -+ "axi", -+ "ahb", -+ "core", -+ "cabac", -+ "hevc_cabac", -+}; -+ -+/* -+ * Some SoCs, like RK3588 have multiple identical vdpu34x cores, but the -+ * kernel is currently missing support for multi-core handling. Exposing -+ * separate devices for each core to userspace is bad, since that does -+ * not allow scheduling tasks properly (and creates ABI). With this workaround -+ * the driver will only probe for the first core and early exit for the other -+ * cores. Once the driver gains multi-core support, the same technique -+ * for detecting the main core can be used to cluster all cores together. -+ */ -+static int rkvdec2_disable_multicore(struct rkvdec2_dev *rkvdec) -+{ -+ const char *compatible; -+ struct device_node *node; -+ int ret; -+ -+ /* Intentionally ignores the fallback strings */ -+ ret = of_property_read_string(rkvdec->dev->of_node, "compatible", &compatible); -+ if (ret) -+ return ret; -+ -+ /* first compatible node found from the root node is considered the main core */ -+ node = of_find_compatible_node(NULL, NULL, compatible); -+ if (!node) -+ return -EINVAL; /* broken DT? */ -+ -+ if (rkvdec->dev->of_node != node) { -+ dev_info(rkvdec->dev, "missing multi-core support, ignoring this instance\n"); -+ return -ENODEV; -+ } -+ -+ return 0; -+} -+ -+static int rkvdec2_probe(struct platform_device *pdev) -+{ -+ struct rkvdec2_dev *rkvdec; -+ unsigned int i; -+ int ret, irq; -+ -+ rkvdec = devm_kzalloc(&pdev->dev, sizeof(*rkvdec), GFP_KERNEL); -+ if (!rkvdec) -+ return -ENOMEM; -+ -+ platform_set_drvdata(pdev, rkvdec); -+ rkvdec->dev = &pdev->dev; -+ -+ ret = rkvdec2_disable_multicore(rkvdec); -+ if (ret) -+ return ret; -+ -+ mutex_init(&rkvdec->vdev_lock); -+ INIT_DELAYED_WORK(&rkvdec->watchdog_work, rkvdec2_watchdog_func); -+ -+ rkvdec->clocks = devm_kcalloc(&pdev->dev, ARRAY_SIZE(rkvdec2_clk_names), -+ sizeof(*rkvdec->clocks), GFP_KERNEL); -+ if (!rkvdec->clocks) -+ return -ENOMEM; -+ -+ for (i = 0; i < ARRAY_SIZE(rkvdec2_clk_names); i++) -+ rkvdec->clocks[i].id = rkvdec2_clk_names[i]; -+ -+ ret = devm_clk_bulk_get(&pdev->dev, ARRAY_SIZE(rkvdec2_clk_names), -+ rkvdec->clocks); -+ if (ret) -+ return ret; -+ -+ rkvdec->regs = devm_platform_ioremap_resource_byname(pdev, "function"); -+ if (IS_ERR(rkvdec->regs)) -+ return PTR_ERR(rkvdec->regs); -+ -+ /* -+ * Without IOMMU support, keep DMA in the lower 32 bits. -+ */ -+ ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); -+ if (ret) { -+ dev_err(&pdev->dev, "Could not set DMA coherent mask.\n"); -+ return ret; -+ } -+ -+ vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32)); -+ -+ irq = platform_get_irq(pdev, 0); -+ if (irq <= 0) -+ return -ENXIO; -+ -+ ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, -+ rkvdec2_irq_handler, IRQF_ONESHOT, -+ dev_name(&pdev->dev), rkvdec); -+ if (ret) { -+ dev_err(&pdev->dev, "Could not request vdec2 IRQ\n"); -+ return ret; -+ } -+ -+ rkvdec->sram_pool = of_gen_pool_get(pdev->dev.of_node, "sram", 0); -+ if (!rkvdec->sram_pool) -+ dev_info(&pdev->dev, "No sram node, RCB will be stored in RAM\n"); -+ -+ pm_runtime_set_autosuspend_delay(&pdev->dev, 100); -+ pm_runtime_use_autosuspend(&pdev->dev); -+ pm_runtime_enable(&pdev->dev); -+ -+ ret = rkvdec2_v4l2_init(rkvdec); -+ if (ret) -+ goto err_disable_runtime_pm; -+ -+ return 0; -+ -+err_disable_runtime_pm: -+ pm_runtime_dont_use_autosuspend(&pdev->dev); -+ pm_runtime_disable(&pdev->dev); -+ -+ if (rkvdec->sram_pool) -+ gen_pool_destroy(rkvdec->sram_pool); -+ -+ return ret; -+} -+ -+static void rkvdec2_remove(struct platform_device *pdev) -+{ -+ struct rkvdec2_dev *rkvdec = platform_get_drvdata(pdev); -+ -+ cancel_delayed_work_sync(&rkvdec->watchdog_work); -+ -+ rkvdec2_v4l2_cleanup(rkvdec); -+ pm_runtime_disable(&pdev->dev); -+ pm_runtime_dont_use_autosuspend(&pdev->dev); -+ -+ if (rkvdec->sram_pool) -+ gen_pool_destroy(rkvdec->sram_pool); -+} -+ -+#ifdef CONFIG_PM -+static int rkvdec2_runtime_resume(struct device *dev) -+{ -+ struct rkvdec2_dev *rkvdec = dev_get_drvdata(dev); -+ -+ return clk_bulk_prepare_enable(ARRAY_SIZE(rkvdec2_clk_names), -+ rkvdec->clocks); -+} -+ -+static int rkvdec2_runtime_suspend(struct device *dev) -+{ -+ struct rkvdec2_dev *rkvdec = dev_get_drvdata(dev); -+ -+ clk_bulk_disable_unprepare(ARRAY_SIZE(rkvdec2_clk_names), -+ rkvdec->clocks); -+ return 0; -+} -+#endif -+ -+static const struct dev_pm_ops rkvdec2_pm_ops = { -+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, -+ pm_runtime_force_resume) -+ SET_RUNTIME_PM_OPS(rkvdec2_runtime_suspend, rkvdec2_runtime_resume, NULL) -+}; -+ -+static struct platform_driver rkvdec2_driver = { -+ .probe = rkvdec2_probe, -+ .remove_new = rkvdec2_remove, -+ .driver = { -+ .name = "rkvdec2", -+ .of_match_table = of_rkvdec2_match, -+ .pm = &rkvdec2_pm_ops, -+ }, -+}; -+module_platform_driver(rkvdec2_driver); -+ -+MODULE_AUTHOR("Detlev Casanova <detlev.casanova@collabora.com>"); -+MODULE_DESCRIPTION("Rockchip Video Decoder 2 driver"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/media/platform/rockchip/rkvdec2/rkvdec2.h b/drivers/media/platform/rockchip/rkvdec2/rkvdec2.h -new file mode 100644 -index 000000000000..8613051775e9 ---- /dev/null -+++ b/drivers/media/platform/rockchip/rkvdec2/rkvdec2.h -@@ -0,0 +1,130 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Rockchip Video Decoder 2 driver -+ * -+ * Copyright (C) 2024 Collabora, Ltd. -+ * Detlev Casanova <detlev.casanova@collabora.com> -+ * -+ * Based on rkvdec driver by Boris Brezillon <boris.brezillon@collabora.com> -+ */ -+#ifndef RKVDEC_H_ -+#define RKVDEC_H_ -+ -+#include <linux/platform_device.h> -+#include <linux/videodev2.h> -+#include <linux/wait.h> -+#include <linux/clk.h> -+#include <linux/dma-mapping.h> -+ -+#include <media/v4l2-ctrls.h> -+#include <media/v4l2-device.h> -+#include <media/v4l2-ioctl.h> -+#include <media/videobuf2-core.h> -+#include <media/videobuf2-dma-contig.h> -+ -+#include "rkvdec2-regs.h" -+ -+#define RKVDEC2_RCB_COUNT 10 -+ -+struct rkvdec2_ctx; -+ -+enum rkvdec2_alloc_type { -+ RKVDEC2_ALLOC_SRAM, -+ RKVDEC2_ALLOC_DMA, -+}; -+ -+struct rkvdec2_aux_buf { -+ void *cpu; -+ dma_addr_t dma; -+ size_t size; -+ enum rkvdec2_alloc_type type; -+}; -+ -+struct rkvdec2_ctrl_desc { -+ struct v4l2_ctrl_config cfg; -+}; -+ -+struct rkvdec2_ctrls { -+ const struct rkvdec2_ctrl_desc *ctrls; -+ unsigned int num_ctrls; -+}; -+ -+struct rkvdec2_run { -+ struct { -+ struct vb2_v4l2_buffer *src; -+ struct vb2_v4l2_buffer *dst; -+ } bufs; -+}; -+ -+struct rkvdec2_decoded_buffer { -+ /* Must be the first field in this struct. */ -+ struct v4l2_m2m_buffer base; -+}; -+ -+static inline struct rkvdec2_decoded_buffer * -+vb2_to_rkvdec2_decoded_buf(struct vb2_buffer *buf) -+{ -+ return container_of(buf, struct rkvdec2_decoded_buffer, -+ base.vb.vb2_buf); -+} -+ -+struct rkvdec2_coded_fmt_ops { -+ int (*adjust_fmt)(struct rkvdec2_ctx *ctx, -+ struct v4l2_format *f); -+ int (*start)(struct rkvdec2_ctx *ctx); -+ void (*stop)(struct rkvdec2_ctx *ctx); -+ int (*run)(struct rkvdec2_ctx *ctx); -+ void (*done)(struct rkvdec2_ctx *ctx, struct vb2_v4l2_buffer *src_buf, -+ struct vb2_v4l2_buffer *dst_buf, -+ enum vb2_buffer_state result); -+ int (*try_ctrl)(struct rkvdec2_ctx *ctx, struct v4l2_ctrl *ctrl); -+}; -+ -+struct rkvdec2_coded_fmt_desc { -+ u32 fourcc; -+ struct v4l2_frmsize_stepwise frmsize; -+ const struct rkvdec2_ctrls *ctrls; -+ const struct rkvdec2_coded_fmt_ops *ops; -+ unsigned int num_decoded_fmts; -+ const u32 *decoded_fmts; -+ u32 subsystem_flags; -+}; -+ -+struct rkvdec2_dev { -+ struct v4l2_device v4l2_dev; -+ struct media_device mdev; -+ struct video_device vdev; -+ struct v4l2_m2m_dev *m2m_dev; -+ struct device *dev; -+ struct clk_bulk_data *clocks; -+ void __iomem *regs; -+ struct gen_pool *sram_pool; -+ struct mutex vdev_lock; /* serializes ioctls */ -+ struct delayed_work watchdog_work; -+}; -+ -+struct rkvdec2_ctx { -+ struct v4l2_fh fh; -+ struct v4l2_format coded_fmt; -+ struct v4l2_format decoded_fmt; -+ const struct rkvdec2_coded_fmt_desc *coded_fmt_desc; -+ struct v4l2_ctrl_handler ctrl_hdl; -+ struct rkvdec2_dev *dev; -+ struct rkvdec2_aux_buf rcb_bufs[RKVDEC2_RCB_COUNT]; -+ -+ u32 colmv_offset; -+ -+ void *priv; -+}; -+ -+static inline struct rkvdec2_ctx *fh_to_rkvdec2_ctx(struct v4l2_fh *fh) -+{ -+ return container_of(fh, struct rkvdec2_ctx, fh); -+} -+ -+void rkvdec2_run_preamble(struct rkvdec2_ctx *ctx, struct rkvdec2_run *run); -+void rkvdec2_run_postamble(struct rkvdec2_ctx *ctx, struct rkvdec2_run *run); -+ -+extern const struct rkvdec2_coded_fmt_ops rkvdec2_h264_fmt_ops; -+ -+#endif /* RKVDEC_H_ */ --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0022-media-dt-bindings-rockchip-Document-RK3588-Video-Dec.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0022-media-dt-bindings-rockchip-Document-RK3588-Video-Dec.patch deleted file mode 100644 index 37f7e5fe41..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0022-media-dt-bindings-rockchip-Document-RK3588-Video-Dec.patch +++ /dev/null @@ -1,142 +0,0 @@ -From 3545c56fe7474e2bb2321a8f7406a5a03af7ed47 Mon Sep 17 00:00:00 2001 -From: Detlev Casanova <detlev.casanova@collabora.com> -Date: Fri, 14 Jun 2024 19:53:40 -0400 -Subject: [PATCH 22/63] media: dt-bindings: rockchip: Document RK3588 Video - Decoder bindings - -Document the Rockchip RK3588 Video Decoder bindings. - -Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com> ---- - .../bindings/media/rockchip,vdec.yaml | 73 ++++++++++++++++++- - 1 file changed, 72 insertions(+), 1 deletion(-) - -diff --git a/Documentation/devicetree/bindings/media/rockchip,vdec.yaml b/Documentation/devicetree/bindings/media/rockchip,vdec.yaml -index 08b02ec16755..bb79499bebb0 100644 ---- a/Documentation/devicetree/bindings/media/rockchip,vdec.yaml -+++ b/Documentation/devicetree/bindings/media/rockchip,vdec.yaml -@@ -17,6 +17,7 @@ properties: - compatible: - oneOf: - - const: rockchip,rk3399-vdec -+ - const: rockchip,rk3588-vdec - - items: - - enum: - - rockchip,rk3228-vdec -@@ -24,35 +25,72 @@ properties: - - const: rockchip,rk3399-vdec - - reg: -- maxItems: 1 -+ minItems: 1 -+ items: -+ - description: The link table configuration registers base -+ - description: The function configuration registers base -+ - description: The cache configuration registers base -+ -+ reg-names: -+ items: -+ - const: link -+ - const: function -+ - const: cache - - interrupts: - maxItems: 1 - - clocks: -+ minItems: 4 - items: - - description: The Video Decoder AXI interface clock - - description: The Video Decoder AHB interface clock - - description: The Video Decoded CABAC clock - - description: The Video Decoder core clock -+ - description: The Video decoder HEVC CABAC clock - - clock-names: -+ minItems: 4 - items: - - const: axi - - const: ahb - - const: cabac - - const: core -+ - const: hevc_cabac - - assigned-clocks: true - - assigned-clock-rates: true - -+ resets: -+ items: -+ - description: The Video Decoder AXI interface reset -+ - description: The Video Decoder AHB interface reset -+ - description: The Video Decoded CABAC reset -+ - description: The Video Decoder core reset -+ - description: The Video decoder HEVC CABAC reset -+ -+ reset-names: -+ items: -+ - const: axi -+ - const: ahb -+ - const: cabac -+ - const: core -+ - const: hevc_cabac -+ - power-domains: - maxItems: 1 - - iommus: - maxItems: 1 - -+ sram: -+ $ref: /schemas/types.yaml#/definitions/phandle -+ description: | -+ phandle to a reserved on-chip SRAM regions. -+ Some SoCs, like rk3588 provide on-chip SRAM to store temporary -+ buffers during decoding. -+ - required: - - compatible - - reg -@@ -61,6 +99,39 @@ required: - - clock-names - - power-domains - -+allOf: -+ - if: -+ properties: -+ compatible: -+ contains: -+ const: rockchip,rk3588-vdec -+ then: -+ properties: -+ reg: -+ minItems: 3 -+ reg-names: -+ minItems: 3 -+ clocks: -+ minItems: 5 -+ clock-names: -+ minItems: 5 -+ resets: -+ minItems: 5 -+ reset-names: -+ minItems: 5 -+ else: -+ properties: -+ reg: -+ maxItems: 1 -+ reg-names: false -+ clocks: -+ maxItems: 4 -+ clock-names: -+ maxItems: 4 -+ resets: false -+ reset-names: false -+ sram: false -+ - additionalProperties: false - - examples: --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0023-arm64-dts-rockchip-Add-rkvdec2-Video-Decoder-on-rk35.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0023-arm64-dts-rockchip-Add-rkvdec2-Video-Decoder-on-rk35.patch deleted file mode 100644 index 5440b400e7..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0023-arm64-dts-rockchip-Add-rkvdec2-Video-Decoder-on-rk35.patch +++ /dev/null @@ -1,82 +0,0 @@ -From a58e96bd39d4595e451c8595f6a7b581875ecc1f Mon Sep 17 00:00:00 2001 -From: Detlev Casanova <detlev.casanova@collabora.com> -Date: Fri, 14 Jun 2024 19:56:19 -0400 -Subject: [PATCH 23/63] arm64: dts: rockchip: Add rkvdec2 Video Decoder on - rk3588(s) - -Add the rkvdec2 Video Decoder to the RK3588s devicetree. - -Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com> ---- - arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 48 +++++++++++++++++++ - 1 file changed, 48 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi -index 11ad0487eaab..2a166eb1aa99 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi -@@ -1238,6 +1238,44 @@ vepu121_3_mmu: iommu@fdbac800 { - #iommu-cells = <0>; - }; - -+ vdec0: video-decoder@fdc38000 { -+ compatible = "rockchip,rk3588-vdec"; -+ reg = <0x0 0xfdc38000 0x0 0x100>, <0x0 0xfdc38100 0x0 0x500>, <0x0 0xfdc38600 0x0 0x100>; -+ reg-names = "link", "function", "cache"; -+ interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH 0>; -+ clocks = <&cru ACLK_RKVDEC0>, <&cru HCLK_RKVDEC0>, <&cru CLK_RKVDEC0_CA>, -+ <&cru CLK_RKVDEC0_CORE>, <&cru CLK_RKVDEC0_HEVC_CA>; -+ clock-names = "axi", "ahb", "cabac", "core", "hevc_cabac"; -+ assigned-clocks = <&cru ACLK_RKVDEC0>, <&cru CLK_RKVDEC0_CORE>, -+ <&cru CLK_RKVDEC0_CA>, <&cru CLK_RKVDEC0_HEVC_CA>; -+ assigned-clock-rates = <800000000>, <600000000>, -+ <600000000>, <1000000000>; -+ resets = <&cru SRST_A_RKVDEC0>, <&cru SRST_H_RKVDEC0>, <&cru SRST_RKVDEC0_CA>, -+ <&cru SRST_RKVDEC0_CORE>, <&cru SRST_RKVDEC0_HEVC_CA>; -+ reset-names = "axi", "ahb", "cabac", "core", "hevc_cabac"; -+ power-domains = <&power RK3588_PD_RKVDEC0>; -+ sram = <&vdec0_sram>; -+ }; -+ -+ vdec1: video-decoder@fdc40000 { -+ compatible = "rockchip,rk3588-vdec"; -+ reg = <0x0 0xfdc40000 0x0 0x100>, <0x0 0xfdc40100 0x0 0x500>, <0x0 0xfdc40600 0x0 0x100>; -+ reg-names = "link", "function", "cache"; -+ interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH 0>; -+ clocks = <&cru ACLK_RKVDEC1>, <&cru HCLK_RKVDEC1>, <&cru CLK_RKVDEC1_CA>, -+ <&cru CLK_RKVDEC1_CORE>, <&cru CLK_RKVDEC1_HEVC_CA>; -+ clock-names = "axi", "ahb", "cabac", "core", "hevc_cabac"; -+ assigned-clocks = <&cru ACLK_RKVDEC1>, <&cru CLK_RKVDEC1_CORE>, -+ <&cru CLK_RKVDEC1_CA>, <&cru CLK_RKVDEC1_HEVC_CA>; -+ assigned-clock-rates = <800000000>, <600000000>, -+ <600000000>, <1000000000>; -+ resets = <&cru SRST_A_RKVDEC1>, <&cru SRST_H_RKVDEC1>, <&cru SRST_RKVDEC1_CA>, -+ <&cru SRST_RKVDEC1_CORE>, <&cru SRST_RKVDEC1_HEVC_CA>; -+ reset-names = "axi", "ahb", "cabac", "core", "hevc_cabac"; -+ power-domains = <&power RK3588_PD_RKVDEC1>; -+ sram = <&vdec1_sram>; -+ }; -+ - av1d: video-codec@fdc70000 { - compatible = "rockchip,rk3588-av1-vpu"; - reg = <0x0 0xfdc70000 0x0 0x800>; -@@ -2849,6 +2887,16 @@ system_sram2: sram@ff001000 { - ranges = <0x0 0x0 0xff001000 0xef000>; - #address-cells = <1>; - #size-cells = <1>; -+ -+ vdec0_sram: codec-sram@0 { -+ reg = <0x0 0x78000>; -+ pool; -+ }; -+ -+ vdec1_sram: codec-sram@78000 { -+ reg = <0x78000 0x77000>; -+ pool; -+ }; - }; - - pinctrl: pinctrl { --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0024-arm64-defconfig-enable-Rockchip-RK3588-video-decoder.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0024-arm64-defconfig-enable-Rockchip-RK3588-video-decoder.patch deleted file mode 100644 index de96a2f88d..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0024-arm64-defconfig-enable-Rockchip-RK3588-video-decoder.patch +++ /dev/null @@ -1,28 +0,0 @@ -From cd119a6a076ca1fa267e6f0c2e946d99da23ccdc Mon Sep 17 00:00:00 2001 -From: Sebastian Reichel <sebastian.reichel@collabora.com> -Date: Mon, 8 Jul 2024 13:31:54 +0200 -Subject: [PATCH 24/63] arm64: defconfig: enable Rockchip RK3588 video decoder - -Enable driver for the Rockchip RK3588 video decoder, which will -also be used by the RK3566/RK3568 in the future. - -Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> ---- - arch/arm64/configs/defconfig | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig -index 5fdbfea7a5b2..5a2912bd9ce5 100644 ---- a/arch/arm64/configs/defconfig -+++ b/arch/arm64/configs/defconfig -@@ -843,6 +843,7 @@ CONFIG_VIDEO_RENESAS_FCP=m - CONFIG_VIDEO_RENESAS_FDP1=m - CONFIG_VIDEO_RENESAS_VSP1=m - CONFIG_VIDEO_RCAR_DRIF=m -+CONFIG_VIDEO_ROCKCHIP_VDEC2=m - CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC=m - CONFIG_VIDEO_SAMSUNG_S5P_JPEG=m - CONFIG_VIDEO_SAMSUNG_S5P_MFC=m --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0025-mfd-rk8xx-Fix-shutdown-handler.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0025-mfd-rk8xx-Fix-shutdown-handler.patch deleted file mode 100644 index 6b00a8991f..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0025-mfd-rk8xx-Fix-shutdown-handler.patch +++ /dev/null @@ -1,114 +0,0 @@ -From b119dd8f418a4ee32cff65dd23c6982a23e6d657 Mon Sep 17 00:00:00 2001 -From: Sebastian Reichel <sebastian.reichel@collabora.com> -Date: Thu, 25 Jul 2024 18:12:24 +0200 -Subject: [PATCH 25/63] mfd: rk8xx: Fix shutdown handler - -When I converted rk808 to device managed resources I converted the rk808 -specific pm_power_off handler to devm_register_sys_off_handler() using -SYS_OFF_MODE_POWER_OFF_PREPARE, which is allowed to sleep. I did this -because the driver's poweroff function makes use of regmap and the backend -of that might sleep. - -But the PMIC poweroff function will kill off the board power and the -kernel does some extra steps after the prepare handler. Thus the prepare -handler should not be used for the PMIC's poweroff routine. Instead the -normal SYS_OFF_MODE_POWER_OFF phase should be used. The old pm_power_off -method is also being called from there, so this would have been a -cleaner conversion anyways. - -But it still makes sense to investigate the sleep handling and check -if there are any issues. Apparently the Rockchip and Meson I2C drivers -(the only platforms using the PMICs handled by this driver) both have -support for atomic transfers and thus may be called from the proper -poweroff context. - -Things are different on the SPI side. That is so far only used by rk806 -and that one is only used by Rockchip RK3588. Unfortunately the Rockchip -SPI driver does not support atomic transfers. That means this change will -introduce an error splash directly before doing the final power off on all -upstream supported RK3588 boards: - -[ 13.761353] ------------[ cut here ]------------ -[ 13.761764] Voluntary context switch within RCU read-side critical section! -[ 13.761776] WARNING: CPU: 0 PID: 1 at kernel/rcu/tree_plugin.h:330 rcu_note_context_switch+0x3ac/0x404 -[ 13.763219] Modules linked in: -[ 13.763498] CPU: 0 UID: 0 PID: 1 Comm: systemd-shutdow Not tainted 6.10.0-12284-g2818a9a19514 #1499 -[ 13.764297] Hardware name: Rockchip RK3588 EVB1 V10 Board (DT) -[ 13.764812] pstate: 604000c9 (nZCv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--) -[ 13.765427] pc : rcu_note_context_switch+0x3ac/0x404 -[ 13.765871] lr : rcu_note_context_switch+0x3ac/0x404 -[ 13.766314] sp : ffff800084f4b5b0 -[ 13.766609] x29: ffff800084f4b5b0 x28: ffff00040139b800 x27: 00007dfb4439ae80 -[ 13.767245] x26: ffff00040139bc80 x25: 0000000000000000 x24: ffff800082118470 -[ 13.767880] x23: 0000000000000000 x22: ffff000400300000 x21: ffff000400300000 -[ 13.768515] x20: ffff800083a9d600 x19: ffff0004fee48600 x18: fffffffffffed448 -[ 13.769151] x17: 000000040044ffff x16: 005000f2b5503510 x15: 0000000000000048 -[ 13.769787] x14: fffffffffffed490 x13: ffff80008473b3c0 x12: 0000000000000900 -[ 13.770421] x11: 0000000000000300 x10: ffff800084797bc0 x9 : ffff80008473b3c0 -[ 13.771057] x8 : 00000000ffffefff x7 : ffff8000847933c0 x6 : 0000000000000300 -[ 13.771692] x5 : 0000000000000301 x4 : 40000000fffff300 x3 : 0000000000000000 -[ 13.772328] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff000400300000 -[ 13.772964] Call trace: -[ 13.773184] rcu_note_context_switch+0x3ac/0x404 -[ 13.773598] __schedule+0x94/0xb0c -[ 13.773907] schedule+0x34/0x104 -[ 13.774198] schedule_timeout+0x84/0xfc -[ 13.774544] wait_for_completion_timeout+0x78/0x14c -[ 13.774980] spi_transfer_one_message+0x588/0x690 -[ 13.775403] __spi_pump_transfer_message+0x19c/0x4ec -[ 13.775846] __spi_sync+0x2a8/0x3c4 -[ 13.776161] spi_write_then_read+0x120/0x208 -[ 13.776543] rk806_spi_bus_read+0x54/0x88 -[ 13.776905] _regmap_raw_read+0xec/0x16c -[ 13.777257] _regmap_bus_read+0x44/0x7c -[ 13.777601] _regmap_read+0x60/0xd8 -[ 13.777915] _regmap_update_bits+0xf4/0x13c -[ 13.778289] regmap_update_bits_base+0x64/0x98 -[ 13.778686] rk808_power_off+0x70/0xfc -[ 13.779024] sys_off_notify+0x40/0x6c -[ 13.779356] atomic_notifier_call_chain+0x60/0x90 -[ 13.779776] do_kernel_power_off+0x54/0x6c -[ 13.780146] machine_power_off+0x18/0x24 -[ 13.780499] kernel_power_off+0x70/0x7c -[ 13.780845] __do_sys_reboot+0x210/0x270 -[ 13.781198] __arm64_sys_reboot+0x24/0x30 -[ 13.781558] invoke_syscall+0x48/0x10c -[ 13.781897] el0_svc_common+0x3c/0xe8 -[ 13.782228] do_el0_svc+0x20/0x2c -[ 13.782528] el0_svc+0x34/0xd8 -[ 13.782806] el0t_64_sync_handler+0x120/0x12c -[ 13.783197] el0t_64_sync+0x190/0x194 -[ 13.783527] ---[ end trace 0000000000000000 ]--- - -At this point the SPI transaction has already been programmed and the -poweroff will proceed, so the board will shutdown anyways. - -As a side-effect this also works around the prepare shutdown handler not -being called at all on Asus C201 and thus fixes its poweroff -functionality, which regressed due to the conversion from pm_power_off -to using SYS_OFF_MODE_POWER_OFF_PREPARE. - -Fixes: 4fec8a5a85c49 ("mfd: rk808: Convert to device managed resources") -Cc: stable@vger.kernel.org -Reported-by: Urja <urja@urja.dev> -Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> ---- - drivers/mfd/rk8xx-core.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/mfd/rk8xx-core.c b/drivers/mfd/rk8xx-core.c -index 39ab114ea669..b27d14b8fd86 100644 ---- a/drivers/mfd/rk8xx-core.c -+++ b/drivers/mfd/rk8xx-core.c -@@ -788,7 +788,7 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap - if (device_property_read_bool(dev, "rockchip,system-power-controller") || - device_property_read_bool(dev, "system-power-controller")) { - ret = devm_register_sys_off_handler(dev, -- SYS_OFF_MODE_POWER_OFF_PREPARE, SYS_OFF_PRIO_HIGH, -+ SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_HIGH, - &rk808_power_off, rk808); - if (ret) - return dev_err_probe(dev, ret, --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0026-WIP-phy-phy-rockchip-samsung-hdptx-Add-FRL-EARC-supp.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0026-WIP-phy-phy-rockchip-samsung-hdptx-Add-FRL-EARC-supp.patch deleted file mode 100644 index 40a3e5dc33..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0026-WIP-phy-phy-rockchip-samsung-hdptx-Add-FRL-EARC-supp.patch +++ /dev/null @@ -1,548 +0,0 @@ -From dd4b6e0676b97e6e8fbeeaabc8b2cbb4e2e4dd67 Mon Sep 17 00:00:00 2001 -From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> -Date: Mon, 5 Feb 2024 01:38:48 +0200 -Subject: [PATCH 26/63] [WIP] phy: phy-rockchip-samsung-hdptx: Add FRL & EARC - support - -For upstreaming, this requires extending the standard PHY API to support -HDMI configuration options [1]. - -Currently, the bus_width PHY attribute is used to pass clock rate and -flags for 10-bit color depth, FRL and EARC. This is done by the HDMI -bridge driver via phy_set_bus_width(). - -[1]: https://lore.kernel.org/all/20240306101625.795732-3-alexander.stein@ew.tq-group.com/ - -Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> ---- - .../phy/rockchip/phy-rockchip-samsung-hdptx.c | 428 +++++++++++++++++- - 1 file changed, 426 insertions(+), 2 deletions(-) - -diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c -index 9f084697dd05..45db96be3f64 100644 ---- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c -+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c -@@ -193,6 +193,10 @@ - #define LN3_TX_SER_RATE_SEL_HBR3 BIT(2) - - #define HDMI20_MAX_RATE 600000000 -+#define DATA_RATE_MASK 0xFFFFFFF -+#define COLOR_DEPTH_MASK BIT(31) -+#define HDMI_MODE_MASK BIT(30) -+#define HDMI_EARC_MASK BIT(29) - - struct lcpll_config { - u32 bit_rate; -@@ -276,6 +280,7 @@ struct rk_hdptx_phy { - struct clk_bulk_data *clks; - int nr_clks; - struct reset_control_bulk_data rsts[RST_MAX]; -+ bool earc_en; - - /* clk provider */ - struct clk_hw hw; -@@ -284,6 +289,24 @@ struct rk_hdptx_phy { - atomic_t usage_count; - }; - -+static const struct lcpll_config lcpll_cfg[] = { -+ { 48000000, 1, 0, 0, 0x7d, 0x7d, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 2, -+ 0, 0x13, 0x18, 1, 0, 0x20, 0x0c, 1, 0, }, -+ { 40000000, 1, 1, 0, 0x68, 0x68, 1, 1, 0, 0, 0, 1, 1, 1, 1, 9, 0, 1, 1, -+ 0, 2, 3, 1, 0, 0x20, 0x0c, 1, 0, }, -+ { 32000000, 1, 1, 1, 0x6b, 0x6b, 1, 1, 0, 1, 2, 1, 1, 1, 1, 9, 1, 2, 1, -+ 0, 0x0d, 0x18, 1, 0, 0x20, 0x0c, 1, 1, }, -+}; -+ -+static const struct ropll_config ropll_frl_cfg[] = { -+ { 24000000, 0x19, 0x19, 1, 1, 0, 1, 2, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, -+ 0, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, -+ { 18000000, 0x7d, 0x7d, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, -+ 0, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, -+ { 9000000, 0x7d, 0x7d, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, -+ 0, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, -+}; -+ - static const struct ropll_config ropll_tmds_cfg[] = { - { 5940000, 124, 124, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0, - 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, -@@ -459,6 +482,73 @@ static const struct reg_sequence rk_hdtpx_tmds_cmn_init_seq[] = { - REG_SEQ0(CMN_REG(009b), 0x00), - }; - -+static const struct reg_sequence rk_hdtpx_frl_cmn_init_seq[] = { -+ REG_SEQ0(CMN_REG(0011), 0x00), -+ REG_SEQ0(CMN_REG(0017), 0x00), -+ REG_SEQ0(CMN_REG(0026), 0x53), -+ REG_SEQ0(CMN_REG(0030), 0x00), -+ REG_SEQ0(CMN_REG(0031), 0x20), -+ REG_SEQ0(CMN_REG(0032), 0x30), -+ REG_SEQ0(CMN_REG(0033), 0x0b), -+ REG_SEQ0(CMN_REG(0034), 0x23), -+ REG_SEQ0(CMN_REG(0042), 0xb8), -+ REG_SEQ0(CMN_REG(004e), 0x14), -+ REG_SEQ0(CMN_REG(0074), 0x00), -+ REG_SEQ0(CMN_REG(0081), 0x09), -+ REG_SEQ0(CMN_REG(0086), 0x01), -+ REG_SEQ0(CMN_REG(0087), 0x0c), -+ REG_SEQ0(CMN_REG(009b), 0x10), -+}; -+ -+static const struct reg_sequence rk_hdtpx_frl_ropll_cmn_init_seq[] = { -+ REG_SEQ0(CMN_REG(0008), 0x00), -+ REG_SEQ0(CMN_REG(001e), 0x14), -+ REG_SEQ0(CMN_REG(0020), 0x00), -+ REG_SEQ0(CMN_REG(0021), 0x00), -+ REG_SEQ0(CMN_REG(0022), 0x11), -+ REG_SEQ0(CMN_REG(0023), 0x00), -+ REG_SEQ0(CMN_REG(0025), 0x00), -+ REG_SEQ0(CMN_REG(0027), 0x00), -+ REG_SEQ0(CMN_REG(0028), 0x00), -+ REG_SEQ0(CMN_REG(002a), 0x01), -+ REG_SEQ0(CMN_REG(002b), 0x00), -+ REG_SEQ0(CMN_REG(002c), 0x00), -+ REG_SEQ0(CMN_REG(002d), 0x00), -+ REG_SEQ0(CMN_REG(002e), 0x00), -+ REG_SEQ0(CMN_REG(002f), 0x04), -+ REG_SEQ0(CMN_REG(003d), 0x40), -+ REG_SEQ0(CMN_REG(005c), 0x25), -+ REG_SEQ0(CMN_REG(0089), 0x00), -+ REG_SEQ0(CMN_REG(0094), 0x00), -+ REG_SEQ0(CMN_REG(0097), 0x02), -+ REG_SEQ0(CMN_REG(0099), 0x04), -+}; -+ -+static const struct reg_sequence rk_hdtpx_frl_lcpll_cmn_init_seq[] = { -+ REG_SEQ0(CMN_REG(0025), 0x10), -+ REG_SEQ0(CMN_REG(0027), 0x01), -+ REG_SEQ0(CMN_REG(0028), 0x0d), -+ REG_SEQ0(CMN_REG(002e), 0x02), -+ REG_SEQ0(CMN_REG(002f), 0x0d), -+ REG_SEQ0(CMN_REG(003d), 0x00), -+ REG_SEQ0(CMN_REG(0051), 0x00), -+ REG_SEQ0(CMN_REG(0055), 0x00), -+ REG_SEQ0(CMN_REG(0059), 0x11), -+ REG_SEQ0(CMN_REG(005a), 0x03), -+ REG_SEQ0(CMN_REG(005c), 0x05), -+ REG_SEQ0(CMN_REG(005e), 0x07), -+ REG_SEQ0(CMN_REG(0060), 0x01), -+ REG_SEQ0(CMN_REG(0064), 0x07), -+ REG_SEQ0(CMN_REG(0065), 0x00), -+ REG_SEQ0(CMN_REG(0069), 0x00), -+ REG_SEQ0(CMN_REG(006c), 0x00), -+ REG_SEQ0(CMN_REG(0070), 0x01), -+ REG_SEQ0(CMN_REG(0089), 0x02), -+ REG_SEQ0(CMN_REG(0095), 0x00), -+ REG_SEQ0(CMN_REG(0097), 0x00), -+ REG_SEQ0(CMN_REG(0099), 0x00), -+}; -+ - static const struct reg_sequence rk_hdtpx_common_sb_init_seq[] = { - REG_SEQ0(SB_REG(0114), 0x00), - REG_SEQ0(SB_REG(0115), 0x00), -@@ -482,6 +572,17 @@ static const struct reg_sequence rk_hdtpx_tmds_lntop_lowbr_seq[] = { - REG_SEQ0(LNTOP_REG(0205), 0x1f), - }; - -+static const struct reg_sequence rk_hdtpx_frl_lntop_init_seq[] = { -+ REG_SEQ0(LNTOP_REG(0200), 0x04), -+ REG_SEQ0(LNTOP_REG(0201), 0x00), -+ REG_SEQ0(LNTOP_REG(0202), 0x00), -+ REG_SEQ0(LNTOP_REG(0203), 0xf0), -+ REG_SEQ0(LNTOP_REG(0204), 0xff), -+ REG_SEQ0(LNTOP_REG(0205), 0xff), -+ REG_SEQ0(LNTOP_REG(0206), 0x05), -+ REG_SEQ0(LNTOP_REG(0207), 0x0f), -+}; -+ - static const struct reg_sequence rk_hdtpx_common_lane_init_seq[] = { - REG_SEQ0(LANE_REG(0303), 0x0c), - REG_SEQ0(LANE_REG(0307), 0x20), -@@ -560,6 +661,40 @@ static const struct reg_sequence rk_hdtpx_tmds_lane_init_seq[] = { - REG_SEQ0(LANE_REG(0606), 0x1c), - }; - -+static const struct reg_sequence rk_hdtpx_frl_ropll_lane_init_seq[] = { -+ REG_SEQ0(LANE_REG(0312), 0x3c), -+ REG_SEQ0(LANE_REG(0412), 0x3c), -+ REG_SEQ0(LANE_REG(0512), 0x3c), -+ REG_SEQ0(LANE_REG(0612), 0x3c), -+}; -+ -+static const struct reg_sequence rk_hdtpx_frl_lcpll_lane_init_seq[] = { -+ REG_SEQ0(LANE_REG(0312), 0x3c), -+ REG_SEQ0(LANE_REG(0412), 0x3c), -+ REG_SEQ0(LANE_REG(0512), 0x3c), -+ REG_SEQ0(LANE_REG(0612), 0x3c), -+ REG_SEQ0(LANE_REG(0303), 0x2f), -+ REG_SEQ0(LANE_REG(0403), 0x2f), -+ REG_SEQ0(LANE_REG(0503), 0x2f), -+ REG_SEQ0(LANE_REG(0603), 0x2f), -+ REG_SEQ0(LANE_REG(0305), 0x03), -+ REG_SEQ0(LANE_REG(0405), 0x03), -+ REG_SEQ0(LANE_REG(0505), 0x03), -+ REG_SEQ0(LANE_REG(0605), 0x03), -+ REG_SEQ0(LANE_REG(0306), 0xfc), -+ REG_SEQ0(LANE_REG(0406), 0xfc), -+ REG_SEQ0(LANE_REG(0506), 0xfc), -+ REG_SEQ0(LANE_REG(0606), 0xfc), -+ REG_SEQ0(LANE_REG(0305), 0x4f), -+ REG_SEQ0(LANE_REG(0405), 0x4f), -+ REG_SEQ0(LANE_REG(0505), 0x4f), -+ REG_SEQ0(LANE_REG(0605), 0x4f), -+ REG_SEQ0(LANE_REG(0304), 0x14), -+ REG_SEQ0(LANE_REG(0404), 0x14), -+ REG_SEQ0(LANE_REG(0504), 0x14), -+ REG_SEQ0(LANE_REG(0604), 0x14), -+}; -+ - static bool rk_hdptx_phy_is_rw_reg(struct device *dev, unsigned int reg) - { - switch (reg) { -@@ -661,6 +796,47 @@ static int rk_hdptx_post_enable_pll(struct rk_hdptx_phy *hdptx) - return 0; - } - -+static int rk_hdptx_post_power_up(struct rk_hdptx_phy *hdptx) -+{ -+ u32 val; -+ int ret; -+ -+ val = (HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN) << 16 | -+ HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN; -+ regmap_write(hdptx->grf, GRF_HDPTX_CON0, val); -+ -+ usleep_range(10, 15); -+ reset_control_deassert(hdptx->rsts[RST_INIT].rstc); -+ -+ usleep_range(10, 15); -+ val = HDPTX_I_PLL_EN << 16 | HDPTX_I_PLL_EN; -+ regmap_write(hdptx->grf, GRF_HDPTX_CON0, val); -+ -+ usleep_range(10, 15); -+ reset_control_deassert(hdptx->rsts[RST_CMN].rstc); -+ -+ ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS, val, -+ val & HDPTX_O_PLL_LOCK_DONE, 20, 400); -+ if (ret) { -+ dev_err(hdptx->dev, "Failed to get PHY PLL lock: %d\n", ret); -+ return ret; -+ } -+ -+ usleep_range(20, 30); -+ reset_control_deassert(hdptx->rsts[RST_LANE].rstc); -+ -+ ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS, val, -+ val & HDPTX_O_PHY_RDY, 100, 5000); -+ if (ret) { -+ dev_err(hdptx->dev, "Failed to get PHY ready: %d\n", ret); -+ return ret; -+ } -+ -+ dev_dbg(hdptx->dev, "PHY ready\n"); -+ -+ return 0; -+} -+ - static void rk_hdptx_phy_disable(struct rk_hdptx_phy *hdptx) - { - u32 val; -@@ -690,6 +866,99 @@ static void rk_hdptx_phy_disable(struct rk_hdptx_phy *hdptx) - regmap_write(hdptx->grf, GRF_HDPTX_CON0, val); - } - -+static void rk_hdptx_earc_config(struct rk_hdptx_phy *hdptx) -+{ -+ regmap_update_bits(hdptx->regmap, SB_REG(0113), SB_RX_RCAL_OPT_CODE_MASK, -+ FIELD_PREP(SB_RX_RCAL_OPT_CODE_MASK, 1)); -+ regmap_write(hdptx->regmap, SB_REG(011c), 0x04); -+ regmap_update_bits(hdptx->regmap, SB_REG(011b), SB_AFC_TOL_MASK, -+ FIELD_PREP(SB_AFC_TOL_MASK, 3)); -+ regmap_write(hdptx->regmap, SB_REG(0109), 0x05); -+ -+ regmap_update_bits(hdptx->regmap, SB_REG(0120), -+ SB_EARC_EN_MASK | SB_EARC_AFC_EN_MASK, -+ FIELD_PREP(SB_EARC_EN_MASK, 1) | -+ FIELD_PREP(SB_EARC_AFC_EN_MASK, 1)); -+ regmap_update_bits(hdptx->regmap, SB_REG(011b), SB_EARC_SIG_DET_BYPASS_MASK, -+ FIELD_PREP(SB_EARC_SIG_DET_BYPASS_MASK, 1)); -+ regmap_update_bits(hdptx->regmap, SB_REG(011f), -+ SB_PWM_AFC_CTRL_MASK | SB_RCAL_RSTN_MASK, -+ FIELD_PREP(SB_PWM_AFC_CTRL_MASK, 0xc) | -+ FIELD_PREP(SB_RCAL_RSTN_MASK, 1)); -+ regmap_update_bits(hdptx->regmap, SB_REG(0115), SB_READY_DELAY_TIME_MASK, -+ FIELD_PREP(SB_READY_DELAY_TIME_MASK, 2)); -+ regmap_update_bits(hdptx->regmap, SB_REG(0113), SB_RX_RTERM_CTRL_MASK, -+ FIELD_PREP(SB_RX_RTERM_CTRL_MASK, 3)); -+ regmap_update_bits(hdptx->regmap, SB_REG(0102), ANA_SB_RXTERM_OFFSP_MASK, -+ FIELD_PREP(ANA_SB_RXTERM_OFFSP_MASK, 3)); -+ regmap_update_bits(hdptx->regmap, SB_REG(0103), ANA_SB_RXTERM_OFFSN_MASK, -+ FIELD_PREP(ANA_SB_RXTERM_OFFSN_MASK, 3)); -+ -+ regmap_write(hdptx->regmap, SB_REG(011a), 0x03); -+ regmap_write(hdptx->regmap, SB_REG(0118), 0x0a); -+ regmap_write(hdptx->regmap, SB_REG(011e), 0x6a); -+ regmap_write(hdptx->regmap, SB_REG(011d), 0x67); -+ -+ regmap_update_bits(hdptx->regmap, SB_REG(0117), FAST_PULSE_TIME_MASK, -+ FIELD_PREP(FAST_PULSE_TIME_MASK, 4)); -+ regmap_update_bits(hdptx->regmap, SB_REG(0114), -+ SB_TG_SB_EN_DELAY_TIME_MASK | SB_TG_RXTERM_EN_DELAY_TIME_MASK, -+ FIELD_PREP(SB_TG_SB_EN_DELAY_TIME_MASK, 2) | -+ FIELD_PREP(SB_TG_RXTERM_EN_DELAY_TIME_MASK, 2)); -+ regmap_update_bits(hdptx->regmap, SB_REG(0105), ANA_SB_TX_HLVL_PROG_MASK, -+ FIELD_PREP(ANA_SB_TX_HLVL_PROG_MASK, 7)); -+ regmap_update_bits(hdptx->regmap, SB_REG(0106), ANA_SB_TX_LLVL_PROG_MASK, -+ FIELD_PREP(ANA_SB_TX_LLVL_PROG_MASK, 7)); -+ regmap_update_bits(hdptx->regmap, SB_REG(010f), ANA_SB_VREG_GAIN_CTRL_MASK, -+ FIELD_PREP(ANA_SB_VREG_GAIN_CTRL_MASK, 0)); -+ regmap_update_bits(hdptx->regmap, SB_REG(0110), ANA_SB_VREG_REF_SEL_MASK, -+ FIELD_PREP(ANA_SB_VREG_REF_SEL_MASK, 1)); -+ regmap_update_bits(hdptx->regmap, SB_REG(0115), SB_TG_OSC_EN_DELAY_TIME_MASK, -+ FIELD_PREP(SB_TG_OSC_EN_DELAY_TIME_MASK, 2)); -+ regmap_update_bits(hdptx->regmap, SB_REG(0116), AFC_RSTN_DELAY_TIME_MASK, -+ FIELD_PREP(AFC_RSTN_DELAY_TIME_MASK, 2)); -+ regmap_update_bits(hdptx->regmap, SB_REG(0109), ANA_SB_DMRX_AFC_DIV_RATIO_MASK, -+ FIELD_PREP(ANA_SB_DMRX_AFC_DIV_RATIO_MASK, 5)); -+ regmap_update_bits(hdptx->regmap, SB_REG(0103), OVRD_SB_RX_RESCAL_DONE_MASK, -+ FIELD_PREP(OVRD_SB_RX_RESCAL_DONE_MASK, 1)); -+ regmap_update_bits(hdptx->regmap, SB_REG(0104), OVRD_SB_EN_MASK, -+ FIELD_PREP(OVRD_SB_EN_MASK, 1)); -+ regmap_update_bits(hdptx->regmap, SB_REG(0102), OVRD_SB_RXTERM_EN_MASK, -+ FIELD_PREP(OVRD_SB_RXTERM_EN_MASK, 1)); -+ regmap_update_bits(hdptx->regmap, SB_REG(0105), OVRD_SB_EARC_CMDC_EN_MASK, -+ FIELD_PREP(OVRD_SB_EARC_CMDC_EN_MASK, 1)); -+ regmap_update_bits(hdptx->regmap, SB_REG(010f), -+ OVRD_SB_VREG_EN_MASK | OVRD_SB_VREG_LPF_BYPASS_MASK, -+ FIELD_PREP(OVRD_SB_VREG_EN_MASK, 1) | -+ FIELD_PREP(OVRD_SB_VREG_LPF_BYPASS_MASK, 1)); -+ regmap_update_bits(hdptx->regmap, SB_REG(0123), OVRD_SB_READY_MASK, -+ FIELD_PREP(OVRD_SB_READY_MASK, 1)); -+ -+ usleep_range(1000, 1100); -+ regmap_update_bits(hdptx->regmap, SB_REG(0103), SB_RX_RESCAL_DONE_MASK, -+ FIELD_PREP(SB_RX_RESCAL_DONE_MASK, 1)); -+ usleep_range(50, 60); -+ regmap_update_bits(hdptx->regmap, SB_REG(0104), SB_EN_MASK, -+ FIELD_PREP(SB_EN_MASK, 1)); -+ usleep_range(50, 60); -+ regmap_update_bits(hdptx->regmap, SB_REG(0102), SB_RXTERM_EN_MASK, -+ FIELD_PREP(SB_RXTERM_EN_MASK, 1)); -+ usleep_range(50, 60); -+ regmap_update_bits(hdptx->regmap, SB_REG(0105), SB_EARC_CMDC_EN_MASK, -+ FIELD_PREP(SB_EARC_CMDC_EN_MASK, 1)); -+ regmap_update_bits(hdptx->regmap, SB_REG(010f), SB_VREG_EN_MASK, -+ FIELD_PREP(SB_VREG_EN_MASK, 1)); -+ usleep_range(50, 60); -+ regmap_update_bits(hdptx->regmap, SB_REG(010f), OVRD_SB_VREG_LPF_BYPASS_MASK, -+ FIELD_PREP(OVRD_SB_VREG_LPF_BYPASS_MASK, 1)); -+ usleep_range(250, 300); -+ regmap_update_bits(hdptx->regmap, SB_REG(010f), OVRD_SB_VREG_LPF_BYPASS_MASK, -+ FIELD_PREP(OVRD_SB_VREG_LPF_BYPASS_MASK, 0)); -+ usleep_range(100, 120); -+ regmap_update_bits(hdptx->regmap, SB_REG(0123), SB_READY_MASK, -+ FIELD_PREP(SB_READY_MASK, 1)); -+} -+ - static bool rk_hdptx_phy_clk_pll_calc(unsigned int data_rate, - struct ropll_config *cfg) - { -@@ -765,9 +1034,13 @@ static bool rk_hdptx_phy_clk_pll_calc(unsigned int data_rate, - static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx, - unsigned int rate) - { -+ int i, bus_width = phy_get_bus_width(hdptx->phy); -+ u8 color_depth = (bus_width & COLOR_DEPTH_MASK) ? 1 : 0; - const struct ropll_config *cfg = NULL; - struct ropll_config rc = {0}; -- int i; -+ -+ if (color_depth) -+ rate = rate * 10 / 8; - - hdptx->rate = rate * 100; - -@@ -825,6 +1098,9 @@ static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx, - regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_POSTDIV_SEL_MASK, - FIELD_PREP(PLL_PCG_POSTDIV_SEL_MASK, cfg->pms_sdiv)); - -+ regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_CLK_SEL_MASK, -+ FIELD_PREP(PLL_PCG_CLK_SEL_MASK, color_depth)); -+ - regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_CLK_EN, - PLL_PCG_CLK_EN); - -@@ -852,9 +1128,146 @@ static int rk_hdptx_ropll_tmds_mode_config(struct rk_hdptx_phy *hdptx, - rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_lane_init_seq); - rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_lane_init_seq); - -+ if (hdptx->earc_en) -+ rk_hdptx_earc_config(hdptx); -+ - return rk_hdptx_post_enable_lane(hdptx); - } - -+static int rk_hdptx_ropll_frl_mode_config(struct rk_hdptx_phy *hdptx, -+ u32 bus_width) -+{ -+ u32 bit_rate = bus_width & DATA_RATE_MASK; -+ u8 color_depth = (bus_width & COLOR_DEPTH_MASK) ? 1 : 0; -+ const struct ropll_config *cfg = NULL; -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(ropll_frl_cfg); i++) -+ if (bit_rate == ropll_frl_cfg[i].bit_rate) { -+ cfg = &ropll_frl_cfg[i]; -+ break; -+ } -+ -+ if (!cfg) { -+ dev_err(hdptx->dev, "%s cannot find pll cfg\n", __func__); -+ return -EINVAL; -+ } -+ -+ rk_hdptx_pre_power_up(hdptx); -+ -+ reset_control_assert(hdptx->rsts[RST_ROPLL].rstc); -+ usleep_range(10, 20); -+ reset_control_deassert(hdptx->rsts[RST_ROPLL].rstc); -+ -+ rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_cmn_init_seq); -+ rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_frl_cmn_init_seq); -+ rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_frl_ropll_cmn_init_seq); -+ -+ regmap_write(hdptx->regmap, CMN_REG(0051), cfg->pms_mdiv); -+ regmap_write(hdptx->regmap, CMN_REG(0055), cfg->pms_mdiv_afc); -+ regmap_write(hdptx->regmap, CMN_REG(0059), -+ (cfg->pms_pdiv << 4) | cfg->pms_refdiv); -+ regmap_write(hdptx->regmap, CMN_REG(005a), cfg->pms_sdiv << 4); -+ -+ regmap_update_bits(hdptx->regmap, CMN_REG(005e), ROPLL_SDM_EN_MASK, -+ FIELD_PREP(ROPLL_SDM_EN_MASK, cfg->sdm_en)); -+ if (!cfg->sdm_en) -+ regmap_update_bits(hdptx->regmap, CMN_REG(005e), 0xf, 0); -+ -+ regmap_update_bits(hdptx->regmap, CMN_REG(0064), ROPLL_SDM_NUM_SIGN_RBR_MASK, -+ FIELD_PREP(ROPLL_SDM_NUM_SIGN_RBR_MASK, cfg->sdm_num_sign)); -+ -+ regmap_write(hdptx->regmap, CMN_REG(0060), cfg->sdm_deno); -+ regmap_write(hdptx->regmap, CMN_REG(0065), cfg->sdm_num); -+ -+ regmap_update_bits(hdptx->regmap, CMN_REG(0069), ROPLL_SDC_N_RBR_MASK, -+ FIELD_PREP(ROPLL_SDC_N_RBR_MASK, cfg->sdc_n)); -+ -+ regmap_write(hdptx->regmap, CMN_REG(006c), cfg->sdc_num); -+ regmap_write(hdptx->regmap, CMN_REG(0070), cfg->sdc_deno); -+ -+ regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_POSTDIV_SEL_MASK, -+ FIELD_PREP(PLL_PCG_POSTDIV_SEL_MASK, cfg->pms_sdiv)); -+ regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_CLK_SEL_MASK, -+ FIELD_PREP(PLL_PCG_CLK_SEL_MASK, color_depth)); -+ -+ rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_sb_init_seq); -+ rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_frl_lntop_init_seq); -+ -+ rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_lane_init_seq); -+ rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_frl_ropll_lane_init_seq); -+ -+ if (hdptx->earc_en) -+ rk_hdptx_earc_config(hdptx); -+ -+ return rk_hdptx_post_power_up(hdptx); -+} -+ -+static int rk_hdptx_lcpll_frl_mode_config(struct rk_hdptx_phy *hdptx, -+ u32 bus_width) -+{ -+ u32 bit_rate = bus_width & DATA_RATE_MASK; -+ u8 color_depth = (bus_width & COLOR_DEPTH_MASK) ? 1 : 0; -+ const struct lcpll_config *cfg = NULL; -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(lcpll_cfg); i++) -+ if (bit_rate == lcpll_cfg[i].bit_rate) { -+ cfg = &lcpll_cfg[i]; -+ break; -+ } -+ -+ if (!cfg) { -+ dev_err(hdptx->dev, "%s cannot find pll cfg\n", __func__); -+ return -EINVAL; -+ } -+ -+ rk_hdptx_pre_power_up(hdptx); -+ -+ rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_cmn_init_seq); -+ rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_frl_cmn_init_seq); -+ rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_frl_lcpll_cmn_init_seq); -+ -+ regmap_update_bits(hdptx->regmap, CMN_REG(0008), -+ LCPLL_EN_MASK | LCPLL_LCVCO_MODE_EN_MASK, -+ FIELD_PREP(LCPLL_EN_MASK, 1) | -+ FIELD_PREP(LCPLL_LCVCO_MODE_EN_MASK, cfg->lcvco_mode_en)); -+ -+ regmap_update_bits(hdptx->regmap, CMN_REG(001e), -+ LCPLL_PI_EN_MASK | LCPLL_100M_CLK_EN_MASK, -+ FIELD_PREP(LCPLL_PI_EN_MASK, cfg->pi_en) | -+ FIELD_PREP(LCPLL_100M_CLK_EN_MASK, cfg->clk_en_100m)); -+ -+ regmap_write(hdptx->regmap, CMN_REG(0020), cfg->pms_mdiv); -+ regmap_write(hdptx->regmap, CMN_REG(0021), cfg->pms_mdiv_afc); -+ regmap_write(hdptx->regmap, CMN_REG(0022), -+ (cfg->pms_pdiv << 4) | cfg->pms_refdiv); -+ regmap_write(hdptx->regmap, CMN_REG(0023), -+ (cfg->pms_sdiv << 4) | cfg->pms_sdiv); -+ regmap_write(hdptx->regmap, CMN_REG(002a), cfg->sdm_deno); -+ regmap_write(hdptx->regmap, CMN_REG(002b), cfg->sdm_num_sign); -+ regmap_write(hdptx->regmap, CMN_REG(002c), cfg->sdm_num); -+ -+ regmap_update_bits(hdptx->regmap, CMN_REG(002d), LCPLL_SDC_N_MASK, -+ FIELD_PREP(LCPLL_SDC_N_MASK, cfg->sdc_n)); -+ -+ regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_POSTDIV_SEL_MASK, -+ FIELD_PREP(PLL_PCG_POSTDIV_SEL_MASK, cfg->pms_sdiv)); -+ regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_CLK_SEL_MASK, -+ FIELD_PREP(PLL_PCG_CLK_SEL_MASK, color_depth)); -+ -+ rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_sb_init_seq); -+ rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_frl_lntop_init_seq); -+ -+ rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_lane_init_seq); -+ rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_frl_lcpll_lane_init_seq); -+ -+ if (hdptx->earc_en) -+ rk_hdptx_earc_config(hdptx); -+ -+ return rk_hdptx_post_power_up(hdptx); -+} -+ - static int rk_hdptx_phy_consumer_get(struct rk_hdptx_phy *hdptx, - unsigned int rate) - { -@@ -922,11 +1335,22 @@ static int rk_hdptx_phy_power_on(struct phy *phy) - * from the HDMI bridge driver until phy_configure_opts_hdmi - * becomes available in the PHY API. - */ -- unsigned int rate = bus_width & 0xfffffff; -+ unsigned int rate = bus_width & DATA_RATE_MASK; - - dev_dbg(hdptx->dev, "%s bus_width=%x rate=%u\n", - __func__, bus_width, rate); - -+ if (bus_width & HDMI_EARC_MASK) -+ hdptx->earc_en = true; -+ else -+ hdptx->earc_en = false; -+ -+ if (bus_width & HDMI_MODE_MASK) { -+ if (rate > 24000000) -+ return rk_hdptx_lcpll_frl_mode_config(hdptx, bus_width); -+ return rk_hdptx_ropll_frl_mode_config(hdptx, bus_width); -+ } -+ - ret = rk_hdptx_phy_consumer_get(hdptx, rate); - if (ret) - return ret; --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0027-TESTING-phy-phy-rockchip-samsung-hdptx-Add-verbose-l.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0027-TESTING-phy-phy-rockchip-samsung-hdptx-Add-verbose-l.patch deleted file mode 100644 index 42eb573b8f..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0027-TESTING-phy-phy-rockchip-samsung-hdptx-Add-verbose-l.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 4ffaa1f9fd1e21f08d478ce28328750ad313c301 Mon Sep 17 00:00:00 2001 -From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> -Date: Fri, 19 Jan 2024 19:51:32 +0200 -Subject: [PATCH 27/63] [TESTING] phy: phy-rockchip-samsung-hdptx: Add verbose - logging - ---- - drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - -diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c -index 45db96be3f64..5dbc1a482de1 100644 ---- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c -+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c -@@ -841,6 +841,8 @@ static void rk_hdptx_phy_disable(struct rk_hdptx_phy *hdptx) - { - u32 val; - -+ dev_dbg(hdptx->dev, "PHY disable\n"); -+ - /* reset phy and apb, or phy locked flag may keep 1 */ - reset_control_assert(hdptx->rsts[RST_PHY].rstc); - usleep_range(20, 30); -@@ -1366,6 +1368,8 @@ static int rk_hdptx_phy_power_off(struct phy *phy) - { - struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy); - -+ dev_dbg(hdptx->dev, "power_off\n"); -+ - return rk_hdptx_phy_consumer_put(hdptx, false); - } - -@@ -1384,6 +1388,8 @@ static int rk_hdptx_phy_clk_prepare(struct clk_hw *hw) - { - struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw); - -+ dev_dbg(hdptx->dev, "clk_prepare\n"); -+ - return rk_hdptx_phy_consumer_get(hdptx, hdptx->rate / 100); - } - -@@ -1391,6 +1397,8 @@ static void rk_hdptx_phy_clk_unprepare(struct clk_hw *hw) - { - struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw); - -+ dev_dbg(hdptx->dev, "clk_unprepare\n"); -+ - rk_hdptx_phy_consumer_put(hdptx, true); - } - -@@ -1427,6 +1435,8 @@ static int rk_hdptx_phy_clk_set_rate(struct clk_hw *hw, unsigned long rate, - { - struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw); - -+ dev_dbg(hdptx->dev, "clk_set_rate rate=%lu\n", rate); -+ - return rk_hdptx_ropll_tmds_cmn_config(hdptx, rate / 100); - } - -@@ -1472,6 +1482,8 @@ static int rk_hdptx_phy_runtime_suspend(struct device *dev) - { - struct rk_hdptx_phy *hdptx = dev_get_drvdata(dev); - -+ dev_dbg(hdptx->dev, "suspend\n"); -+ - clk_bulk_disable_unprepare(hdptx->nr_clks, hdptx->clks); - - return 0; -@@ -1482,6 +1494,8 @@ static int rk_hdptx_phy_runtime_resume(struct device *dev) - struct rk_hdptx_phy *hdptx = dev_get_drvdata(dev); - int ret; - -+ dev_dbg(hdptx->dev, "resume\n"); -+ - ret = clk_bulk_prepare_enable(hdptx->nr_clks, hdptx->clks); - if (ret) - dev_err(hdptx->dev, "Failed to enable clocks: %d\n", ret); --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0028-WIP-dt-bindings-display-rockchip-drm-Add-optional-cl.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0028-WIP-dt-bindings-display-rockchip-drm-Add-optional-cl.patch deleted file mode 100644 index 393d800487..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0028-WIP-dt-bindings-display-rockchip-drm-Add-optional-cl.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 7359564bae3778c240ac0b625ea4315a16b60bfe Mon Sep 17 00:00:00 2001 -From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> -Date: Wed, 27 Mar 2024 20:36:15 +0200 -Subject: [PATCH 28/63] [WIP] dt-bindings: display: rockchip-drm: Add optional - clocks property - -Allow using the clock provided by HDMI0 PHY PLL to improve HDMI output -support on RK3588 SoC. - -Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> ---- - .../bindings/display/rockchip/rockchip-drm.yaml | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip-drm.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip-drm.yaml -index a8d18a37cb23..9d000760dd6e 100644 ---- a/Documentation/devicetree/bindings/display/rockchip/rockchip-drm.yaml -+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-drm.yaml -@@ -28,6 +28,14 @@ properties: - of vop devices. vop definitions as defined in - Documentation/devicetree/bindings/display/rockchip/rockchip-vop.yaml - -+ clocks: -+ maxItems: 1 -+ description: Optional clock provided by HDMI0 PLL -+ -+ clock-names: -+ items: -+ - const: hdmi0_phy_pll -+ - required: - - compatible - - ports --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0029-WIP-drm-rockchip-vop2-Improve-display-modes-handling.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0029-WIP-drm-rockchip-vop2-Improve-display-modes-handling.patch deleted file mode 100644 index 7704dd6710..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0029-WIP-drm-rockchip-vop2-Improve-display-modes-handling.patch +++ /dev/null @@ -1,680 +0,0 @@ -From 06f9c88855d468c03ee343d7433105b3edc3175d Mon Sep 17 00:00:00 2001 -From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> -Date: Fri, 3 Nov 2023 19:58:02 +0200 -Subject: [PATCH 29/63] [WIP] drm/rockchip: vop2: Improve display modes - handling on rk3588 - -The initial vop2 support for rk3588 in mainline is not able to handle -all display modes supported by connected displays, e.g. -2560x1440-75.00Hz, 2048x1152-60.00Hz, 1024x768-60.00Hz. - -Additionally, it doesn't cope with non-integer refresh rates like 59.94, -29.97, 23.98, etc. - -Improve HDMI0 clocking in order to support the additional display modes. - -Fixes: 5a028e8f062f ("drm/rockchip: vop2: Add support for rk3588") -Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> ---- - drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 553 ++++++++++++++++++- - 1 file changed, 552 insertions(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c -index 6122eb18e6c9..c68d76b25080 100644 ---- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c -+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c -@@ -5,6 +5,8 @@ - */ - #include <linux/bitfield.h> - #include <linux/clk.h> -+#include <linux/clk-provider.h> -+#include <linux/clkdev.h> - #include <linux/component.h> - #include <linux/delay.h> - #include <linux/iopoll.h> -@@ -214,6 +216,10 @@ struct vop2 { - struct clk *hclk; - struct clk *aclk; - struct clk *pclk; -+ // [CC:] hack to support additional display modes -+ struct clk *hdmi0_phy_pll; -+ /* list_head of internal clk */ -+ struct list_head clk_list_head; - - /* optional internal rgb encoder */ - struct rockchip_rgb *rgb; -@@ -222,6 +228,19 @@ struct vop2 { - struct vop2_win win[]; - }; - -+struct vop2_clk { -+ struct vop2 *vop2; -+ struct list_head list; -+ unsigned long rate; -+ struct clk_hw hw; -+ struct clk_divider div; -+ int div_val; -+ u8 parent_index; -+}; -+ -+#define to_vop2_clk(_hw) container_of(_hw, struct vop2_clk, hw) -+#define VOP2_MAX_DCLK_RATE 600000 /* kHz */ -+ - #define vop2_output_if_is_hdmi(x) ((x) == ROCKCHIP_VOP2_EP_HDMI0 || \ - (x) == ROCKCHIP_VOP2_EP_HDMI1) - -@@ -1478,9 +1497,30 @@ static bool vop2_crtc_mode_fixup(struct drm_crtc *crtc, - const struct drm_display_mode *mode, - struct drm_display_mode *adj_mode) - { -+ struct vop2_video_port *vp = to_vop2_video_port(crtc); -+ struct drm_connector *connector; -+ struct drm_connector_list_iter conn_iter; -+ struct drm_crtc_state *new_crtc_state = container_of(mode, struct drm_crtc_state, mode); - drm_mode_set_crtcinfo(adj_mode, CRTC_INTERLACE_HALVE_V | - CRTC_STEREO_DOUBLE); - -+ if (mode->flags & DRM_MODE_FLAG_DBLCLK) -+ adj_mode->crtc_clock *= 2; -+ -+ drm_connector_list_iter_begin(crtc->dev, &conn_iter); -+ drm_for_each_connector_iter(connector, &conn_iter) { -+ if ((new_crtc_state->connector_mask & drm_connector_mask(connector)) && -+ ((connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) || -+ (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA))) { -+ drm_connector_list_iter_end(&conn_iter); -+ return true; -+ } -+ } -+ drm_connector_list_iter_end(&conn_iter); -+ -+ if (adj_mode->crtc_clock <= VOP2_MAX_DCLK_RATE) -+ adj_mode->crtc_clock = DIV_ROUND_UP(clk_round_rate(vp->dclk, -+ adj_mode->crtc_clock * 1000), 1000); - return true; - } - -@@ -1665,6 +1705,31 @@ static unsigned long rk3588_calc_dclk(unsigned long child_clk, unsigned long max - return 0; - } - -+static struct vop2_clk *vop2_clk_get(struct vop2 *vop2, const char *name); -+ -+static int vop2_cru_set_rate(struct vop2_clk *if_pixclk, struct vop2_clk *if_dclk) -+{ -+ int ret = 0; -+ -+ if (if_pixclk) { -+ ret = clk_set_rate(if_pixclk->hw.clk, if_pixclk->rate); -+ if (ret < 0) { -+ DRM_DEV_ERROR(if_pixclk->vop2->dev, "set %s to %ld failed: %d\n", -+ clk_hw_get_name(&if_pixclk->hw), if_pixclk->rate, ret); -+ return ret; -+ } -+ } -+ -+ if (if_dclk) { -+ ret = clk_set_rate(if_dclk->hw.clk, if_dclk->rate); -+ if (ret < 0) -+ DRM_DEV_ERROR(if_dclk->vop2->dev, "set %s to %ld failed %d\n", -+ clk_hw_get_name(&if_dclk->hw), if_dclk->rate, ret); -+ } -+ -+ return ret; -+} -+ - /* - * 4 pixclk/cycle on rk3588 - * RGB/eDP/HDMI: if_pixclk >= dclk_core -@@ -1688,6 +1753,72 @@ static unsigned long rk3588_calc_cru_cfg(struct vop2_video_port *vp, int id, - int K = 1; - - if (vop2_output_if_is_hdmi(id)) { -+ if (vop2->data->soc_id == 3588 && id == ROCKCHIP_VOP2_EP_HDMI0 && -+ vop2->hdmi0_phy_pll) { -+ const char *clk_src_name = "hdmi_edp0_clk_src"; -+ const char *clk_parent_name = "dclk"; -+ const char *pixclk_name = "hdmi_edp0_pixclk"; -+ const char *dclk_name = "hdmi_edp0_dclk"; -+ struct vop2_clk *if_clk_src, *if_clk_parent, *if_pixclk, *if_dclk, *dclk, *dclk_core, *dclk_out; -+ char clk_name[32]; -+ int ret; -+ -+ if_clk_src = vop2_clk_get(vop2, clk_src_name); -+ snprintf(clk_name, sizeof(clk_name), "%s%d", clk_parent_name, vp->id); -+ if_clk_parent = vop2_clk_get(vop2, clk_name); -+ if_pixclk = vop2_clk_get(vop2, pixclk_name); -+ if_dclk = vop2_clk_get(vop2, dclk_name); -+ if (!if_pixclk || !if_clk_parent) { -+ DRM_DEV_ERROR(vop2->dev, "failed to get connector interface clk\n"); -+ return -ENODEV; -+ } -+ -+ ret = clk_set_parent(if_clk_src->hw.clk, if_clk_parent->hw.clk); -+ if (ret < 0) { -+ DRM_DEV_ERROR(vop2->dev, "failed to set parent(%s) for %s: %d\n", -+ __clk_get_name(if_clk_parent->hw.clk), -+ __clk_get_name(if_clk_src->hw.clk), ret); -+ return ret; -+ } -+ -+ if (output_mode == ROCKCHIP_OUT_MODE_YUV420) -+ K = 2; -+ -+ if_pixclk->rate = (dclk_core_rate << 1) / K; -+ if_dclk->rate = dclk_core_rate / K; -+ -+ snprintf(clk_name, sizeof(clk_name), "dclk_core%d", vp->id); -+ dclk_core = vop2_clk_get(vop2, clk_name); -+ -+ snprintf(clk_name, sizeof(clk_name), "dclk_out%d", vp->id); -+ dclk_out = vop2_clk_get(vop2, clk_name); -+ -+ snprintf(clk_name, sizeof(clk_name), "dclk%d", vp->id); -+ dclk = vop2_clk_get(vop2, clk_name); -+ if (v_pixclk <= (VOP2_MAX_DCLK_RATE * 1000)) { -+ if (output_mode == ROCKCHIP_OUT_MODE_YUV420) -+ v_pixclk = v_pixclk >> 1; -+ } else { -+ v_pixclk = v_pixclk >> 2; -+ } -+ clk_set_rate(dclk->hw.clk, v_pixclk); -+ -+ if (dclk_core_rate > if_pixclk->rate) { -+ clk_set_rate(dclk_core->hw.clk, dclk_core_rate); -+ ret = vop2_cru_set_rate(if_pixclk, if_dclk); -+ } else { -+ ret = vop2_cru_set_rate(if_pixclk, if_dclk); -+ clk_set_rate(dclk_core->hw.clk, dclk_core_rate); -+ } -+ -+ *dclk_core_div = dclk_core->div_val; -+ *dclk_out_div = dclk_out->div_val; -+ *if_pixclk_div = if_pixclk->div_val; -+ *if_dclk_div = if_dclk->div_val; -+ -+ return dclk->rate; -+ } -+ - /* - * K = 2: dclk_core = if_pixclk_rate > if_dclk_rate - * K = 1: dclk_core = hdmie_edp_dclk > if_pixclk_rate -@@ -1919,6 +2050,22 @@ static int us_to_vertical_line(struct drm_display_mode *mode, int us) - return us * mode->clock / mode->htotal / 1000; - } - -+// [CC:] rework virtual clock -+static struct vop2_clk *vop2_clk_get(struct vop2 *vop2, const char *name) -+{ -+ struct vop2_clk *clk, *n; -+ -+ if (!name) -+ return NULL; -+ -+ list_for_each_entry_safe(clk, n, &vop2->clk_list_head, list) { -+ if (!strcmp(clk_hw_get_name(&clk->hw), name)) -+ return clk; -+ } -+ -+ return NULL; -+} -+ - static int vop2_clk_reset(struct vop2_video_port *vp) - { - struct reset_control *rstc = vp->dclk_rst; -@@ -1966,6 +2113,8 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, - u32 val, polflags; - int ret; - struct drm_encoder *encoder; -+ char clk_name[32]; -+ struct vop2_clk *dclk; - - 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", -@@ -2066,11 +2215,38 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, - - if (mode->flags & DRM_MODE_FLAG_DBLCLK) { - dsp_ctrl |= RK3568_VP_DSP_CTRL__CORE_DCLK_DIV; -- clock *= 2; -+ // [CC:] done via mode_fixup -+ // clock *= 2; - } - - vop2_vp_write(vp, RK3568_VP_MIPI_CTRL, 0); - -+ snprintf(clk_name, sizeof(clk_name), "dclk%d", vp->id); -+ dclk = vop2_clk_get(vop2, clk_name); -+ if (dclk) { -+ /* -+ * use HDMI_PHY_PLL as dclk source under 4K@60 if it is available, -+ * otherwise use system cru as dclk source. -+ */ -+ drm_for_each_encoder_mask(encoder, crtc->dev, crtc_state->encoder_mask) { -+ struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder); -+ -+ // [CC:] Using PHY PLL to handle all display modes -+ if (rkencoder->crtc_endpoint_id == ROCKCHIP_VOP2_EP_HDMI0) { -+ clk_get_rate(vop2->hdmi0_phy_pll); -+ -+ if (mode->crtc_clock <= VOP2_MAX_DCLK_RATE) { -+ ret = clk_set_parent(vp->dclk, vop2->hdmi0_phy_pll); -+ if (ret < 0) -+ DRM_WARN("failed to set clock parent for %s\n", -+ __clk_get_name(vp->dclk)); -+ } -+ -+ clock = dclk->rate; -+ } -+ } -+ } -+ - clk_set_rate(vp->dclk, clock); - - vop2_post_config(crtc); -@@ -2528,7 +2704,43 @@ static void vop2_crtc_atomic_flush(struct drm_crtc *crtc, - spin_unlock_irq(&crtc->dev->event_lock); - } - -+static enum drm_mode_status -+vop2_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode) -+{ -+ struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->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]; -+ int request_clock = mode->clock; -+ int clock; -+ -+ if (mode->hdisplay > vp_data->max_output.width) -+ return MODE_BAD_HVALUE; -+ -+ if (mode->flags & DRM_MODE_FLAG_DBLCLK) -+ request_clock *= 2; -+ -+ if (request_clock <= VOP2_MAX_DCLK_RATE) { -+ clock = request_clock; -+ } else { -+ request_clock = request_clock >> 2; -+ clock = clk_round_rate(vp->dclk, request_clock * 1000) / 1000; -+ } -+ -+ /* -+ * Hdmi or DisplayPort request a Accurate clock. -+ */ -+ if (vcstate->output_type == DRM_MODE_CONNECTOR_HDMIA || -+ vcstate->output_type == DRM_MODE_CONNECTOR_DisplayPort) -+ if (clock != request_clock) -+ return MODE_CLOCK_RANGE; -+ -+ return MODE_OK; -+} -+ - static const struct drm_crtc_helper_funcs vop2_crtc_helper_funcs = { -+ .mode_valid = vop2_crtc_mode_valid, - .mode_fixup = vop2_crtc_mode_fixup, - .atomic_check = vop2_crtc_atomic_check, - .atomic_begin = vop2_crtc_atomic_begin, -@@ -3104,6 +3316,336 @@ static const struct regmap_config vop2_regmap_config = { - .cache_type = REGCACHE_MAPLE, - }; - -+/* -+ * BEGIN virtual clock -+ */ -+#define PLL_RATE_MIN 30000000 -+ -+#define cru_dbg(format, ...) do { \ -+ if (cru_debug) \ -+ pr_info("%s: " format, __func__, ## __VA_ARGS__); \ -+ } while (0) -+ -+#define PNAME(x) static const char *const x[] -+ -+enum vop_clk_branch_type { -+ branch_mux, -+ branch_divider, -+ branch_factor, -+ branch_virtual, -+}; -+ -+#define VIR(cname) \ -+ { \ -+ .branch_type = branch_virtual, \ -+ .name = cname, \ -+ } -+ -+ -+#define MUX(cname, pnames, f) \ -+ { \ -+ .branch_type = branch_mux, \ -+ .name = cname, \ -+ .parent_names = pnames, \ -+ .num_parents = ARRAY_SIZE(pnames), \ -+ .flags = f, \ -+ } -+ -+#define FACTOR(cname, pname, f) \ -+ { \ -+ .branch_type = branch_factor, \ -+ .name = cname, \ -+ .parent_names = (const char *[]){ pname }, \ -+ .num_parents = 1, \ -+ .flags = f, \ -+ } -+ -+#define DIV(cname, pname, f, w) \ -+ { \ -+ .branch_type = branch_divider, \ -+ .name = cname, \ -+ .parent_names = (const char *[]){ pname }, \ -+ .num_parents = 1, \ -+ .flags = f, \ -+ .div_width = w, \ -+ } -+ -+struct vop2_clk_branch { -+ enum vop_clk_branch_type branch_type; -+ const char *name; -+ const char *const *parent_names; -+ u8 num_parents; -+ unsigned long flags; -+ u8 div_shift; -+ u8 div_width; -+ u8 div_flags; -+}; -+ -+PNAME(mux_port0_dclk_src_p) = { "dclk0", "dclk1" }; -+PNAME(mux_port2_dclk_src_p) = { "dclk2", "dclk1" }; -+PNAME(mux_dp_pixclk_p) = { "dclk_out0", "dclk_out1", "dclk_out2" }; -+PNAME(mux_hdmi_edp_clk_src_p) = { "dclk0", "dclk1", "dclk2" }; -+PNAME(mux_mipi_clk_src_p) = { "dclk_out1", "dclk_out2", "dclk_out3" }; -+PNAME(mux_dsc_8k_clk_src_p) = { "dclk0", "dclk1", "dclk2", "dclk3" }; -+PNAME(mux_dsc_4k_clk_src_p) = { "dclk0", "dclk1", "dclk2", "dclk3" }; -+ -+/* -+ * We only use this clk driver calculate the div -+ * of dclk_core/dclk_out/if_pixclk/if_dclk and -+ * the rate of the dclk from the soc. -+ * -+ * We don't touch the cru in the vop here, as -+ * these registers has special read andy write -+ * limits. -+ */ -+static struct vop2_clk_branch rk3588_vop_clk_branches[] = { -+ VIR("dclk0"), -+ VIR("dclk1"), -+ VIR("dclk2"), -+ VIR("dclk3"), -+ -+ MUX("port0_dclk_src", mux_port0_dclk_src_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT), -+ DIV("dclk_core0", "port0_dclk_src", CLK_SET_RATE_PARENT, 2), -+ DIV("dclk_out0", "port0_dclk_src", CLK_SET_RATE_PARENT, 2), -+ -+ FACTOR("port1_dclk_src", "dclk1", CLK_SET_RATE_PARENT), -+ DIV("dclk_core1", "port1_dclk_src", CLK_SET_RATE_PARENT, 2), -+ DIV("dclk_out1", "port1_dclk_src", CLK_SET_RATE_PARENT, 2), -+ -+ MUX("port2_dclk_src", mux_port2_dclk_src_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT), -+ DIV("dclk_core2", "port2_dclk_src", CLK_SET_RATE_PARENT, 2), -+ DIV("dclk_out2", "port2_dclk_src", CLK_SET_RATE_PARENT, 2), -+ -+ FACTOR("port3_dclk_src", "dclk3", CLK_SET_RATE_PARENT), -+ DIV("dclk_core3", "port3_dclk_src", CLK_SET_RATE_PARENT, 2), -+ DIV("dclk_out3", "port3_dclk_src", CLK_SET_RATE_PARENT, 2), -+ -+ MUX("dp0_pixclk", mux_dp_pixclk_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT), -+ MUX("dp1_pixclk", mux_dp_pixclk_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT), -+ -+ MUX("hdmi_edp0_clk_src", mux_hdmi_edp_clk_src_p, -+ CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT), -+ DIV("hdmi_edp0_dclk", "hdmi_edp0_clk_src", 0, 2), -+ DIV("hdmi_edp0_pixclk", "hdmi_edp0_clk_src", CLK_SET_RATE_PARENT, 1), -+ -+ MUX("hdmi_edp1_clk_src", mux_hdmi_edp_clk_src_p, -+ CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT), -+ DIV("hdmi_edp1_dclk", "hdmi_edp1_clk_src", 0, 2), -+ DIV("hdmi_edp1_pixclk", "hdmi_edp1_clk_src", CLK_SET_RATE_PARENT, 1), -+ -+ MUX("mipi0_clk_src", mux_mipi_clk_src_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT), -+ DIV("mipi0_pixclk", "mipi0_clk_src", CLK_SET_RATE_PARENT, 2), -+ -+ MUX("mipi1_clk_src", mux_mipi_clk_src_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT), -+ DIV("mipi1_pixclk", "mipi1_clk_src", CLK_SET_RATE_PARENT, 2), -+ -+ FACTOR("rgb_pixclk", "port3_dclk_src", CLK_SET_RATE_PARENT), -+ -+ MUX("dsc_8k_txp_clk_src", mux_dsc_8k_clk_src_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT), -+ DIV("dsc_8k_txp_clk", "dsc_8k_txp_clk_src", 0, 2), -+ DIV("dsc_8k_pxl_clk", "dsc_8k_txp_clk_src", 0, 2), -+ DIV("dsc_8k_cds_clk", "dsc_8k_txp_clk_src", 0, 2), -+ -+ MUX("dsc_4k_txp_clk_src", mux_dsc_4k_clk_src_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT), -+ DIV("dsc_4k_txp_clk", "dsc_4k_txp_clk_src", 0, 2), -+ DIV("dsc_4k_pxl_clk", "dsc_4k_txp_clk_src", 0, 2), -+ DIV("dsc_4k_cds_clk", "dsc_4k_txp_clk_src", 0, 2), -+}; -+ -+static unsigned long clk_virtual_recalc_rate(struct clk_hw *hw, -+ unsigned long parent_rate) -+{ -+ struct vop2_clk *vop2_clk = to_vop2_clk(hw); -+ -+ return (unsigned long)vop2_clk->rate; -+} -+ -+static long clk_virtual_round_rate(struct clk_hw *hw, unsigned long rate, -+ unsigned long *prate) -+{ -+ struct vop2_clk *vop2_clk = to_vop2_clk(hw); -+ -+ vop2_clk->rate = rate; -+ -+ return rate; -+} -+ -+static int clk_virtual_set_rate(struct clk_hw *hw, unsigned long rate, -+ unsigned long parent_rate) -+{ -+ return 0; -+} -+ -+const struct clk_ops clk_virtual_ops = { -+ .round_rate = clk_virtual_round_rate, -+ .set_rate = clk_virtual_set_rate, -+ .recalc_rate = clk_virtual_recalc_rate, -+}; -+ -+static u8 vop2_mux_get_parent(struct clk_hw *hw) -+{ -+ struct vop2_clk *vop2_clk = to_vop2_clk(hw); -+ -+ // cru_dbg("%s index: %d\n", clk_hw_get_name(hw), vop2_clk->parent_index); -+ return vop2_clk->parent_index; -+} -+ -+static int vop2_mux_set_parent(struct clk_hw *hw, u8 index) -+{ -+ struct vop2_clk *vop2_clk = to_vop2_clk(hw); -+ -+ vop2_clk->parent_index = index; -+ -+ // cru_dbg("%s index: %d\n", clk_hw_get_name(hw), index); -+ return 0; -+} -+ -+static int vop2_clk_mux_determine_rate(struct clk_hw *hw, -+ struct clk_rate_request *req) -+{ -+ // cru_dbg("%s %ld(min: %ld max: %ld)\n", -+ // clk_hw_get_name(hw), req->rate, req->min_rate, req->max_rate); -+ return __clk_mux_determine_rate(hw, req); -+} -+ -+static const struct clk_ops vop2_mux_clk_ops = { -+ .get_parent = vop2_mux_get_parent, -+ .set_parent = vop2_mux_set_parent, -+ .determine_rate = vop2_clk_mux_determine_rate, -+}; -+ -+#define div_mask(width) ((1 << (width)) - 1) -+ -+static int vop2_div_get_val(unsigned long rate, unsigned long parent_rate) -+{ -+ unsigned int div, value; -+ -+ div = DIV_ROUND_UP_ULL((u64)parent_rate, rate); -+ -+ value = ilog2(div); -+ -+ return value; -+} -+ -+static unsigned long vop2_clk_div_recalc_rate(struct clk_hw *hw, -+ unsigned long parent_rate) -+{ -+ struct vop2_clk *vop2_clk = to_vop2_clk(hw); -+ unsigned long rate; -+ unsigned int div; -+ -+ div = 1 << vop2_clk->div_val; -+ rate = parent_rate / div; -+ -+ // cru_dbg("%s rate: %ld(prate: %ld)\n", clk_hw_get_name(hw), rate, parent_rate); -+ return rate; -+} -+ -+static long vop2_clk_div_round_rate(struct clk_hw *hw, unsigned long rate, -+ unsigned long *prate) -+{ -+ struct vop2_clk *vop2_clk = to_vop2_clk(hw); -+ -+ if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) { -+ if (*prate < rate) -+ *prate = rate; -+ if ((*prate >> vop2_clk->div.width) > rate) -+ *prate = rate; -+ -+ if ((*prate % rate)) -+ *prate = rate; -+ -+ /* SOC PLL can't output a too low pll freq */ -+ if (*prate < PLL_RATE_MIN) -+ *prate = rate << vop2_clk->div.width; -+ } -+ -+ // cru_dbg("%s rate: %ld(prate: %ld)\n", clk_hw_get_name(hw), rate, *prate); -+ return rate; -+} -+ -+static int vop2_clk_div_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) -+{ -+ struct vop2_clk *vop2_clk = to_vop2_clk(hw); -+ int div_val; -+ -+ div_val = vop2_div_get_val(rate, parent_rate); -+ vop2_clk->div_val = div_val; -+ -+ // cru_dbg("%s prate: %ld rate: %ld div_val: %d\n", -+ // clk_hw_get_name(hw), parent_rate, rate, div_val); -+ return 0; -+} -+ -+static const struct clk_ops vop2_div_clk_ops = { -+ .recalc_rate = vop2_clk_div_recalc_rate, -+ .round_rate = vop2_clk_div_round_rate, -+ .set_rate = vop2_clk_div_set_rate, -+}; -+ -+static struct clk *vop2_clk_register(struct vop2 *vop2, struct vop2_clk_branch *branch) -+{ -+ struct clk_init_data init = {}; -+ struct vop2_clk *vop2_clk; -+ struct clk *clk; -+ -+ vop2_clk = devm_kzalloc(vop2->dev, sizeof(*vop2_clk), GFP_KERNEL); -+ if (!vop2_clk) -+ return ERR_PTR(-ENOMEM); -+ -+ vop2_clk->vop2 = vop2; -+ vop2_clk->hw.init = &init; -+ vop2_clk->div.shift = branch->div_shift; -+ vop2_clk->div.width = branch->div_width; -+ -+ init.name = branch->name; -+ init.flags = branch->flags; -+ init.num_parents = branch->num_parents; -+ init.parent_names = branch->parent_names; -+ if (branch->branch_type == branch_divider) { -+ init.ops = &vop2_div_clk_ops; -+ } else if (branch->branch_type == branch_virtual) { -+ init.ops = &clk_virtual_ops; -+ init.num_parents = 0; -+ init.parent_names = NULL; -+ } else { -+ init.ops = &vop2_mux_clk_ops; -+ } -+ -+ clk = devm_clk_register(vop2->dev, &vop2_clk->hw); -+ if (!IS_ERR(clk)) -+ list_add_tail(&vop2_clk->list, &vop2->clk_list_head); -+ else -+ DRM_DEV_ERROR(vop2->dev, "Register %s failed\n", branch->name); -+ -+ return clk; -+} -+ -+static int vop2_clk_init(struct vop2 *vop2) -+{ -+ struct vop2_clk_branch *branch = rk3588_vop_clk_branches; -+ unsigned int nr_clk = ARRAY_SIZE(rk3588_vop_clk_branches); -+ unsigned int idx; -+ struct vop2_clk *clk, *n; -+ -+ INIT_LIST_HEAD(&vop2->clk_list_head); -+ -+ if (vop2->data->soc_id < 3588 || vop2->hdmi0_phy_pll == NULL) -+ return 0; -+ -+ list_for_each_entry_safe(clk, n, &vop2->clk_list_head, list) { -+ list_del(&clk->list); -+ } -+ -+ for (idx = 0; idx < nr_clk; idx++, branch++) -+ vop2_clk_register(vop2, branch); -+ -+ return 0; -+} -+/* -+ * END virtual clock -+ */ -+ - static int vop2_bind(struct device *dev, struct device *master, void *data) - { - struct platform_device *pdev = to_platform_device(dev); -@@ -3197,6 +3739,12 @@ static int vop2_bind(struct device *dev, struct device *master, void *data) - return PTR_ERR(vop2->pclk); - } - -+ vop2->hdmi0_phy_pll = devm_clk_get_optional(vop2->drm->dev, "hdmi0_phy_pll"); -+ if (IS_ERR(vop2->hdmi0_phy_pll)) { -+ DRM_DEV_ERROR(vop2->dev, "failed to get hdmi0_phy_pll source\n"); -+ return PTR_ERR(vop2->hdmi0_phy_pll); -+ } -+ - vop2->irq = platform_get_irq(pdev, 0); - if (vop2->irq < 0) { - drm_err(vop2->drm, "cannot find irq for vop2\n"); -@@ -3213,6 +3761,9 @@ static int vop2_bind(struct device *dev, struct device *master, void *data) - if (ret) - return ret; - -+ // [CC:] rework virtual clock -+ vop2_clk_init(vop2); -+ - ret = vop2_find_rgb_encoder(vop2); - if (ret >= 0) { - vop2->rgb = rockchip_rgb_init(dev, &vop2->vps[ret].crtc, --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0030-arm64-dts-rockchip-Add-HDMI0-bridge-to-rk3588.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0030-arm64-dts-rockchip-Add-HDMI0-bridge-to-rk3588.patch deleted file mode 100644 index dbf5569e20..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0030-arm64-dts-rockchip-Add-HDMI0-bridge-to-rk3588.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 85df9ddee8798c170ae16d568ac14729ca2c82d4 Mon Sep 17 00:00:00 2001 -From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> -Date: Mon, 15 Jan 2024 22:47:41 +0200 -Subject: [PATCH 30/63] arm64: dts: rockchip: Add HDMI0 bridge to rk3588 - -Add DT node for the HDMI0 bridge found on RK3588 SoC. - -Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> ---- - arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 41 +++++++++++++++++++ - 1 file changed, 41 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi -index 2a166eb1aa99..e003d67cca79 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi -@@ -1416,6 +1416,47 @@ i2s9_8ch: i2s@fddfc000 { - status = "disabled"; - }; - -+ hdmi0: hdmi@fde80000 { -+ compatible = "rockchip,rk3588-dw-hdmi-qp"; -+ reg = <0x0 0xfde80000 0x0 0x20000>; -+ clocks = <&cru PCLK_HDMITX0>, -+ <&cru CLK_HDMIHDP0>, -+ <&cru CLK_HDMITX0_EARC>, -+ <&cru CLK_HDMITX0_REF>, -+ <&cru MCLK_I2S5_8CH_TX>, -+ <&cru HCLK_VO1>; -+ clock-names = "pclk", "hdp", "earc", "ref", "aud", "hclk_vo1"; -+ interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH 0>, -+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH 0>, -+ <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH 0>, -+ <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH 0>, -+ <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH 0>; -+ phys = <&hdptxphy_hdmi0>; -+ phy-names = "hdmi"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&hdmim0_tx0_cec &hdmim0_tx0_hpd -+ &hdmim0_tx0_scl &hdmim0_tx0_sda>; -+ power-domains = <&power RK3588_PD_VO1>; -+ resets = <&cru SRST_HDMITX0_REF>, <&cru SRST_HDMIHDP0>; -+ reset-names = "ref", "hdp"; -+ rockchip,grf = <&sys_grf>; -+ rockchip,vo1_grf = <&vo1_grf>; -+ status = "disabled"; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ hdmi0_in: port@0 { -+ reg = <0>; -+ }; -+ -+ hdmi0_out: port@1 { -+ reg = <1>; -+ }; -+ }; -+ }; -+ - qos_gpu_m0: qos@fdf35000 { - compatible = "rockchip,rk3588-qos", "syscon"; - reg = <0x0 0xfdf35000 0x0 0x20>; --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0031-arm64-dts-rockchip-Enable-HDMI0-on-rock-5b.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0031-arm64-dts-rockchip-Enable-HDMI0-on-rock-5b.patch deleted file mode 100644 index 8df9f82736..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0031-arm64-dts-rockchip-Enable-HDMI0-on-rock-5b.patch +++ /dev/null @@ -1,91 +0,0 @@ -From fcf6418b2af8b5384d5c3c120809a7a4b9edd845 Mon Sep 17 00:00:00 2001 -From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> -Date: Mon, 15 Jan 2024 22:51:17 +0200 -Subject: [PATCH 31/63] arm64: dts: rockchip: Enable HDMI0 on rock-5b - -Add the necessary DT changes to enable HDMI0 on Rock 5B. - -Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> ---- - .../boot/dts/rockchip/rk3588-rock-5b.dts | 47 +++++++++++++++++++ - 1 file changed, 47 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts -index b8717606517c..cd6ec47b2197 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts -@@ -4,6 +4,7 @@ - - #include <dt-bindings/gpio/gpio.h> - #include <dt-bindings/leds/common.h> -+#include <dt-bindings/soc/rockchip,vop2.h> - #include <dt-bindings/usb/pd.h> - #include "rk3588.dtsi" - -@@ -38,6 +39,17 @@ analog-sound { - pinctrl-0 = <&hp_detect>; - }; - -+ hdmi0-con { -+ compatible = "hdmi-connector"; -+ type = "a"; -+ -+ port { -+ hdmi0_con_in: endpoint { -+ remote-endpoint = <&hdmi0_out_con>; -+ }; -+ }; -+ }; -+ - leds { - compatible = "gpio-leds"; - pinctrl-names = "default"; -@@ -203,6 +215,26 @@ &gpu { - status = "okay"; - }; - -+&hdmi0 { -+ status = "okay"; -+}; -+ -+&hdmi0_in { -+ hdmi0_in_vp0: endpoint { -+ remote-endpoint = <&vp0_out_hdmi0>; -+ }; -+}; -+ -+&hdmi0_out { -+ hdmi0_out_con: endpoint { -+ remote-endpoint = <&hdmi0_con_in>; -+ }; -+}; -+ -+&hdptxphy_hdmi0 { -+ status = "okay"; -+}; -+ - &i2c0 { - pinctrl-names = "default"; - pinctrl-0 = <&i2c0m2_xfer>; -@@ -979,3 +1011,18 @@ &usb_host1_xhci { - &usb_host2_xhci { - status = "okay"; - }; -+ -+&vop_mmu { -+ status = "okay"; -+}; -+ -+&vop { -+ status = "okay"; -+}; -+ -+&vp0 { -+ vp0_out_hdmi0: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { -+ reg = <ROCKCHIP_VOP2_EP_HDMI0>; -+ remote-endpoint = <&hdmi0_in_vp0>; -+ }; -+}; --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0032-arm64-dts-rockchip-Enable-HDMI0-on-rk3588-evb1.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0032-arm64-dts-rockchip-Enable-HDMI0-on-rk3588-evb1.patch deleted file mode 100644 index 74be3475a7..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0032-arm64-dts-rockchip-Enable-HDMI0-on-rk3588-evb1.patch +++ /dev/null @@ -1,91 +0,0 @@ -From 6c5d019d97ad7dadd8c480786bc895d32415217d Mon Sep 17 00:00:00 2001 -From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> -Date: Wed, 17 Jan 2024 01:53:38 +0200 -Subject: [PATCH 32/63] arm64: dts: rockchip: Enable HDMI0 on rk3588-evb1 - -Add the necessary DT changes to enable HDMI0 on Rockchip RK3588 EVB1. - -Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> ---- - .../boot/dts/rockchip/rk3588-evb1-v10.dts | 47 +++++++++++++++++++ - 1 file changed, 47 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts -index 6f6af801e7f3..8d0f402c7243 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts -@@ -9,6 +9,7 @@ - #include <dt-bindings/gpio/gpio.h> - #include <dt-bindings/input/input.h> - #include <dt-bindings/pinctrl/rockchip.h> -+#include <dt-bindings/soc/rockchip,vop2.h> - #include <dt-bindings/usb/pd.h> - #include "rk3588.dtsi" - -@@ -129,6 +130,17 @@ bluetooth-rfkill { - pinctrl-0 = <&bluetooth_pwren>; - }; - -+ hdmi0-con { -+ compatible = "hdmi-connector"; -+ type = "a"; -+ -+ port { -+ hdmi0_con_in: endpoint { -+ remote-endpoint = <&hdmi0_out_con>; -+ }; -+ }; -+ }; -+ - pcie20_avdd0v85: pcie20-avdd0v85-regulator { - compatible = "regulator-fixed"; - regulator-name = "pcie20_avdd0v85"; -@@ -309,6 +321,26 @@ &gpu { - status = "okay"; - }; - -+&hdmi0 { -+ status = "okay"; -+}; -+ -+&hdmi0_in { -+ hdmi0_in_vp0: endpoint { -+ remote-endpoint = <&vp0_out_hdmi0>; -+ }; -+}; -+ -+&hdmi0_out { -+ hdmi0_out_con: endpoint { -+ remote-endpoint = <&hdmi0_con_in>; -+ }; -+}; -+ -+&hdptxphy_hdmi0 { -+ status = "okay"; -+}; -+ - &i2c2 { - status = "okay"; - -@@ -1279,3 +1311,18 @@ &usb_host1_xhci { - dr_mode = "host"; - status = "okay"; - }; -+ -+&vop_mmu { -+ status = "okay"; -+}; -+ -+&vop { -+ status = "okay"; -+}; -+ -+&vp0 { -+ vp0_out_hdmi0: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { -+ reg = <ROCKCHIP_VOP2_EP_HDMI0>; -+ remote-endpoint = <&hdmi0_in_vp0>; -+ }; -+}; --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0033-WIP-arm64-dts-rockchip-Enable-HDMI0-PHY-clk-provider.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0033-WIP-arm64-dts-rockchip-Enable-HDMI0-PHY-clk-provider.patch deleted file mode 100644 index 9928b700bb..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0033-WIP-arm64-dts-rockchip-Enable-HDMI0-PHY-clk-provider.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 26b3c270af6218470e1efc917a4eccb8d69e9fc4 Mon Sep 17 00:00:00 2001 -From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> -Date: Tue, 16 Jan 2024 03:13:38 +0200 -Subject: [PATCH 33/63] [WIP] arm64: dts: rockchip: Enable HDMI0 PHY clk - provider on rk3588 - -The HDMI0 PHY can be used as a clock provider on RK3588, hence add the -missing #clock-cells property. ---- - arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi -index e003d67cca79..ab07e3deff69 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi -@@ -2857,6 +2857,7 @@ hdptxphy_hdmi0: phy@fed60000 { - reg = <0x0 0xfed60000 0x0 0x2000>; - clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>, <&cru PCLK_HDPTX0>; - clock-names = "ref", "apb"; -+ #clock-cells = <0>; - #phy-cells = <0>; - resets = <&cru SRST_HDPTX0>, <&cru SRST_P_HDPTX0>, - <&cru SRST_HDPTX0_INIT>, <&cru SRST_HDPTX0_CMN>, --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0034-WIP-arm64-dts-rockchip-Make-use-of-HDMI0-PHY-PLL-on-.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0034-WIP-arm64-dts-rockchip-Make-use-of-HDMI0-PHY-PLL-on-.patch deleted file mode 100644 index d271b1b5a2..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0034-WIP-arm64-dts-rockchip-Make-use-of-HDMI0-PHY-PLL-on-.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0814bb18112d191ef2a986a3cd822a5a556dbf94 Mon Sep 17 00:00:00 2001 -From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> -Date: Fri, 3 Nov 2023 20:05:05 +0200 -Subject: [PATCH 34/63] [WIP] arm64: dts: rockchip: Make use of HDMI0 PHY PLL - on rock-5b - -The initial vop2 support for rk3588 in mainline is not able to handle -all display modes supported by connected displays, e.g. -2560x1440-75.00Hz, 2048x1152-60.00Hz, 1024x768-60.00Hz. - -Additionally, it doesn't cope with non-integer refresh rates like 59.94, -29.97, 23.98, etc. - -Make use of the HDMI0 PHY PLL to support the additional display modes. - -Note this requires commit "drm/rockchip: vop2: Improve display modes -handling on rk3588", which needs a rework to be upstreamable. - -Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> ---- - arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts -index cd6ec47b2197..4d84b95235a5 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts -@@ -210,6 +210,11 @@ &cpu_l3 { - cpu-supply = <&vdd_cpu_lit_s0>; - }; - -+&display_subsystem { -+ clocks = <&hdptxphy_hdmi0>; -+ clock-names = "hdmi0_phy_pll"; -+}; -+ - &gpu { - mali-supply = <&vdd_gpu_s0>; - status = "okay"; --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0035-WIP-arm64-dts-rockchip-Make-use-of-HDMI0-PHY-PLL-on-.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0035-WIP-arm64-dts-rockchip-Make-use-of-HDMI0-PHY-PLL-on-.patch deleted file mode 100644 index 16fb67d3b8..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0035-WIP-arm64-dts-rockchip-Make-use-of-HDMI0-PHY-PLL-on-.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 04179fc6b8e24c0736d47290308717481d2ba284 Mon Sep 17 00:00:00 2001 -From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> -Date: Wed, 17 Jan 2024 02:00:41 +0200 -Subject: [PATCH 35/63] [WIP] arm64: dts: rockchip: Make use of HDMI0 PHY PLL - on rk3588-evb1 - -The initial vop2 support for rk3588 in mainline is not able to handle -all display modes supported by connected displays, e.g. -2560x1440-75.00Hz, 2048x1152-60.00Hz, 1024x768-60.00Hz. - -Additionally, it doesn't cope with non-integer refresh rates like 59.94, -29.97, 23.98, etc. - -Make use of the HDMI0 PHY PLL to support the additional display modes. - -Note this requires commit "drm/rockchip: vop2: Improve display modes -handling on rk3588", which needs a rework to be upstreamable. - -Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> ---- - arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts -index 8d0f402c7243..07c77c369b19 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts -@@ -300,6 +300,11 @@ &cpu_l3 { - cpu-supply = <&vdd_cpu_lit_s0>; - }; - -+&display_subsystem { -+ clocks = <&hdptxphy_hdmi0>; -+ clock-names = "hdmi0_phy_pll"; -+}; -+ - &gmac0 { - clock_in_out = "output"; - phy-handle = <&rgmii_phy>; --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0036-dt-bindings-display-bridge-Add-schema-for-Synopsys-D.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0036-dt-bindings-display-bridge-Add-schema-for-Synopsys-D.patch deleted file mode 100644 index eeb12b0ea0..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0036-dt-bindings-display-bridge-Add-schema-for-Synopsys-D.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 196805991d1fbf63cb7dca0d31812e75381b5b4c Mon Sep 17 00:00:00 2001 -From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> -Date: Fri, 26 Jul 2024 02:54:52 +0300 -Subject: [PATCH 36/63] dt-bindings: display: bridge: Add schema for Synopsys - DW HDMI QP TX - -Add dt-binding schema containing the common properties for the Synopsys -DesignWare HDMI QP TX controller. - -Note this is not a full dt-binding specification, but is meant to be -referenced by platform-specific bindings for this IP core. - -Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> ---- - .../display/bridge/synopsys,dw-hdmi-qp.yaml | 42 +++++++++++++++++++ - 1 file changed, 42 insertions(+) - create mode 100644 Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi-qp.yaml - -diff --git a/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi-qp.yaml b/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi-qp.yaml -new file mode 100644 -index 000000000000..f2135f0f2018 ---- /dev/null -+++ b/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi-qp.yaml -@@ -0,0 +1,42 @@ -+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/display/bridge/synopsys,dw-hdmi-qp.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: Common Properties for Synopsys DesignWare HDMI QP TX Controller IP -+ -+maintainers: -+ - Cristian Ciocaltea <cristian.ciocaltea@collabora.com> -+ -+description: | -+ This document defines device tree properties for the Synopsys DesignWare -+ HDMI 2.1 Quad-Pixel (QP) TX controller IP core. -+ It doesn't constitute a device tree binding specification by itself, but -+ is meant to be referenced by platform-specific device tree bindings. -+ -+ When referenced from platform device tree bindings, the properties defined -+ in this document are defined as follows. The platform device tree bindings -+ are responsible for defining whether each property is required or optional. -+ -+properties: -+ reg: -+ maxItems: 1 -+ -+ clocks: -+ maxItems: 6 -+ items: -+ - description: Peripheral/APB bus clock -+ additionalItems: true -+ -+ clock-names: -+ maxItems: 6 -+ items: -+ - const: pclk -+ additionalItems: true -+ -+ interrupts: -+ minItems: 1 -+ maxItems: 5 -+ -+additionalProperties: true --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0037-dt-bindings-display-rockchip-Add-schema-for-RK3588-H.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0037-dt-bindings-display-rockchip-Add-schema-for-RK3588-H.patch deleted file mode 100644 index 628ecc58b2..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0037-dt-bindings-display-rockchip-Add-schema-for-RK3588-H.patch +++ /dev/null @@ -1,195 +0,0 @@ -From 1a28a98129e311c6ca393af90ddc48cc822ab91a Mon Sep 17 00:00:00 2001 -From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> -Date: Fri, 26 Jul 2024 03:07:04 +0300 -Subject: [PATCH 37/63] dt-bindings: display: rockchip: Add schema for RK3588 - HDMI QP TX controller - -Rockchip RK3588 SoC integrates the Synopsys DesignWare HDMI 2.1 -Quad-Pixel (QP) TX controller. - -Since this is a new IP block, quite different from those used in the -previous generations of Rockchip SoCs, add a new binding file for it. - -Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> ---- - .../display/rockchip/rockchip,dw-hdmi-qp.yaml | 168 ++++++++++++++++++ - 1 file changed, 168 insertions(+) - create mode 100644 Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi-qp.yaml - -diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi-qp.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi-qp.yaml -new file mode 100644 -index 000000000000..f178ea138606 ---- /dev/null -+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi-qp.yaml -@@ -0,0 +1,168 @@ -+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/display/rockchip/rockchip,dw-hdmi-qp.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: Rockchip DW HDMI QP TX Encoder -+ -+maintainers: -+ - Cristian Ciocaltea <cristian.ciocaltea@collabora.com> -+ -+description: -+ Rockchip RK3588 SoC integrates the Synopsys DesignWare HDMI QP TX controller -+ IP and a HDMI/eDP TX Combo PHY based on a Samsung IP block. -+ -+allOf: -+ - $ref: ../bridge/synopsys,dw-hdmi-qp.yaml# -+ - $ref: /schemas/sound/dai-common.yaml# -+ -+properties: -+ compatible: -+ enum: -+ - rockchip,rk3588-dw-hdmi-qp -+ -+ clocks: -+ minItems: 1 -+ items: -+ - {} -+ # The next clocks are optional, but shall be specified in this -+ # order when present. -+ - description: TMDS/FRL link clock -+ - description: EARC RX biphase clock -+ - description: Reference clock -+ - description: Audio interface clock -+ - description: Video datapath clock -+ -+ clock-names: -+ minItems: 1 -+ items: -+ - {} -+ - enum: [hdp, earc, ref, aud, hclk_vo1] -+ - enum: [earc, ref, aud, hclk_vo1] -+ - enum: [ref, aud, hclk_vo1] -+ - enum: [aud, hclk_vo1] -+ - const: hclk_vo1 -+ -+ phys: -+ maxItems: 1 -+ description: The HDMI/eDP PHY. -+ -+ phy-names: -+ const: hdmi -+ -+ ports: -+ $ref: /schemas/graph.yaml#/properties/ports -+ -+ properties: -+ port@0: -+ $ref: /schemas/graph.yaml#/properties/port -+ description: -+ Port node with one endpoint connected to a vop node. -+ -+ port@1: -+ $ref: /schemas/graph.yaml#/properties/port -+ description: -+ Port node with one endpoint connected to a hdmi-connector node. -+ -+ required: -+ - port@0 -+ - port@1 -+ -+ power-domains: -+ maxItems: 1 -+ -+ resets: -+ minItems: 2 -+ maxItems: 2 -+ -+ reset-names: -+ items: -+ - const: ref -+ - const: hdp -+ -+ "#sound-dai-cells": -+ const: 0 -+ -+ rockchip,grf: -+ $ref: /schemas/types.yaml#/definitions/phandle -+ description: -+ Most HDMI QP related data is accessed through SYS GRF regs. -+ -+ rockchip,vo1_grf: -+ $ref: /schemas/types.yaml#/definitions/phandle -+ description: -+ Additional HDMI QP related data is accessed through VO1 GRF regs. -+ -+required: -+ - compatible -+ - reg -+ - clocks -+ - clock-names -+ - interrupts -+ - ports -+ - resets -+ - reset-names -+ - rockchip,grf -+ - rockchip,vo1_grf -+ -+unevaluatedProperties: false -+ -+examples: -+ - | -+ #include <dt-bindings/clock/rockchip,rk3588-cru.h> -+ #include <dt-bindings/interrupt-controller/arm-gic.h> -+ #include <dt-bindings/interrupt-controller/irq.h> -+ #include <dt-bindings/power/rk3588-power.h> -+ #include <dt-bindings/reset/rockchip,rk3588-cru.h> -+ -+ soc { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ -+ hdmi@fde80000 { -+ compatible = "rockchip,rk3588-dw-hdmi-qp"; -+ reg = <0x0 0xfde80000 0x0 0x20000>; -+ interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH 0>, -+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH 0>, -+ <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH 0>, -+ <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH 0>, -+ <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH 0>; -+ clocks = <&cru PCLK_HDMITX0>, -+ <&cru CLK_HDMIHDP0>, -+ <&cru CLK_HDMITX0_EARC>, -+ <&cru CLK_HDMITX0_REF>, -+ <&cru MCLK_I2S5_8CH_TX>, -+ <&cru HCLK_VO1>; -+ clock-names = "pclk", "hdp", "earc", "ref", "aud", "hclk_vo1"; -+ resets = <&cru SRST_HDMITX0_REF>, <&cru SRST_HDMIHDP0>; -+ reset-names = "ref", "hdp"; -+ phys = <&hdptxphy_hdmi0>; -+ phy-names = "hdmi"; -+ power-domains = <&power RK3588_PD_VO1>; -+ rockchip,grf = <&sys_grf>; -+ rockchip,vo1_grf = <&vo1_grf>; -+ #sound-dai-cells = <0>; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ hdmi0_in: port@0 { -+ reg = <0>; -+ -+ hdmi0_in_vp0: endpoint { -+ remote-endpoint = <&vp0_out_hdmi0>; -+ }; -+ }; -+ -+ hdmi0_out: port@1 { -+ reg = <1>; -+ -+ hdmi0_out_con0: endpoint { -+ remote-endpoint = <&hdmi_con0_in>; -+ }; -+ }; -+ }; -+ }; -+ }; --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0038-drm-bridge-synopsys-Add-DW-HDMI-QP-TX-controller-dri.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0038-drm-bridge-synopsys-Add-DW-HDMI-QP-TX-controller-dri.patch deleted file mode 100644 index 1d604309d1..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0038-drm-bridge-synopsys-Add-DW-HDMI-QP-TX-controller-dri.patch +++ /dev/null @@ -1,1719 +0,0 @@ -From 987b25616e5c69bb787a6865029fac5787d16baf Mon Sep 17 00:00:00 2001 -From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> -Date: Mon, 20 May 2024 14:49:50 +0300 -Subject: [PATCH 38/63] drm/bridge: synopsys: Add DW HDMI QP TX controller - driver - -The Synopsys DesignWare HDMI 2.1 Quad-Pixel (QP) TX controller supports -the following features, among others: - -* Fixed Rate Link (FRL) -* 4K@120Hz and 8K@60Hz video modes -* Variable Refresh Rate (VRR) including Quick Media Switching (QMS), aka - Cinema VRR -* Fast Vactive (FVA), aka Quick Frame Transport (QFT) -* SCDC I2C DDC access -* TMDS Scrambler enabling 2160p@60Hz with RGB/YCbCr4:4:4 -* YCbCr4:2:0 enabling 2160p@60Hz at lower HDMI link speeds -* Multi-stream audio -* Enhanced Audio Return Channel (EARC) - -Add driver to enable basic support, i.e. RGB output up to 4K@60Hz, -without audio, CEC or any HDMI 2.1 specific features. - -Co-developed-by: Algea Cao <algea.cao@rock-chips.com> -Signed-off-by: Algea Cao <algea.cao@rock-chips.com> -Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> ---- - drivers/gpu/drm/bridge/synopsys/Kconfig | 8 + - drivers/gpu/drm/bridge/synopsys/Makefile | 2 + - drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 726 ++++++++++++++++ - drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.h | 834 +++++++++++++++++++ - include/drm/bridge/dw_hdmi.h | 8 + - include/drm/bridge/dw_hdmi_qp.h | 37 + - 6 files changed, 1615 insertions(+) - create mode 100644 drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c - create mode 100644 drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.h - create mode 100644 include/drm/bridge/dw_hdmi_qp.h - -diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig b/drivers/gpu/drm/bridge/synopsys/Kconfig -index 15fc182d05ef..ca416dab156d 100644 ---- a/drivers/gpu/drm/bridge/synopsys/Kconfig -+++ b/drivers/gpu/drm/bridge/synopsys/Kconfig -@@ -46,6 +46,14 @@ config DRM_DW_HDMI_CEC - Support the CE interface which is part of the Synopsys - Designware HDMI block. - -+config DRM_DW_HDMI_QP -+ tristate -+ select DRM_DISPLAY_HDMI_HELPER -+ select DRM_DISPLAY_HDMI_STATE_HELPER -+ select DRM_DISPLAY_HELPER -+ select DRM_KMS_HELPER -+ select REGMAP_MMIO -+ - config DRM_DW_MIPI_DSI - tristate - select DRM_KMS_HELPER -diff --git a/drivers/gpu/drm/bridge/synopsys/Makefile b/drivers/gpu/drm/bridge/synopsys/Makefile -index ce715562e9e5..9869d9651ed1 100644 ---- a/drivers/gpu/drm/bridge/synopsys/Makefile -+++ b/drivers/gpu/drm/bridge/synopsys/Makefile -@@ -5,4 +5,6 @@ obj-$(CONFIG_DRM_DW_HDMI_GP_AUDIO) += dw-hdmi-gp-audio.o - obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o - obj-$(CONFIG_DRM_DW_HDMI_CEC) += dw-hdmi-cec.o - -+obj-$(CONFIG_DRM_DW_HDMI_QP) += dw-hdmi-qp.o -+ - obj-$(CONFIG_DRM_DW_MIPI_DSI) += dw-mipi-dsi.o -diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c -new file mode 100644 -index 000000000000..b878c4e23833 ---- /dev/null -+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c -@@ -0,0 +1,726 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ * Copyright (c) 2021-2022 Rockchip Electronics Co., Ltd. -+ * Copyright (c) 2024 Collabora Ltd. -+ * -+ * Author: Algea Cao <algea.cao@rock-chips.com> -+ * Author: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> -+ */ -+#include <linux/completion.h> -+#include <linux/hdmi.h> -+#include <linux/i2c.h> -+#include <linux/irq.h> -+#include <linux/module.h> -+#include <linux/mutex.h> -+#include <linux/of.h> -+ -+#include <drm/bridge/dw_hdmi_qp.h> -+#include <drm/display/drm_hdmi_state_helper.h> -+#include <drm/display/drm_scdc_helper.h> -+ -+#include <drm/drm_atomic.h> -+#include <drm/drm_atomic_helper.h> -+#include <drm/drm_bridge.h> -+#include <drm/drm_connector.h> -+#include <drm/drm_edid.h> -+ -+#include <sound/hdmi-codec.h> -+ -+#include "dw-hdmi-qp.h" -+ -+#define DDC_CI_ADDR 0x37 -+#define DDC_SEGMENT_ADDR 0x30 -+ -+/* DW-HDMI Controller >= 0x200a are at least compliant with SCDC version 1 */ -+#define SCDC_MIN_SOURCE_VERSION 0x1 -+ -+#define HDMI14_MAX_TMDSCLK 340000000 -+ -+struct dw_hdmi_qp_i2c { -+ struct i2c_adapter adap; -+ -+ struct mutex lock; /* used to serialize data transfers */ -+ struct completion cmp; -+ u8 stat; -+ -+ u8 slave_reg; -+ bool is_regaddr; -+ bool is_segment; -+}; -+ -+struct dw_hdmi_qp { -+ struct drm_bridge bridge; -+ -+ struct device *dev; -+ struct dw_hdmi_qp_i2c *i2c; -+ -+ struct { -+ const struct dw_hdmi_qp_phy_ops *ops; -+ void *data; -+ } phy; -+ -+ //TODO: drop curr_conn and/or pix_clock -+ struct drm_connector *curr_conn; -+ unsigned long long pix_clock; -+ -+ struct regmap *regm; -+}; -+ -+/* Filter out invalid setups to avoid configuring SCDC and scrambling */ -+static bool dw_hdmi_qp_support_scdc(struct dw_hdmi_qp *hdmi, -+ const struct drm_display_info *display) -+{ -+ /* Disable if no DDC bus */ -+ if (!hdmi->bridge.ddc) -+ return false; -+ -+ /* Disable if SCDC is not supported, or if an HF-VSDB block is absent */ -+ if (!display->hdmi.scdc.supported || -+ !display->hdmi.scdc.scrambling.supported) -+ return false; -+ -+ /* -+ * Disable if display only support low TMDS rates and scrambling -+ * for low rates is not supported either -+ */ -+ if (!display->hdmi.scdc.scrambling.low_rates && -+ display->max_tmds_clock <= 340000) -+ return false; -+ -+ return true; -+} -+ -+/* -+ * HDMI2.0 Specifies the following procedure for High TMDS Bit Rates: -+ * - The Source shall suspend transmission of the TMDS clock and data -+ * -+ * - The Source shall write to the TMDS_Bit_Clock_Ratio bit to change it -+ * from a 0 to a 1 or from a 1 to a 0 -+ * -+ * - The Source shall allow a minimum of 1 ms and a maximum of 100 ms from -+ * the time the TMDS_Bit_Clock_Ratio bit is written until resuming -+ * transmission of TMDS clock and data -+ * -+ * To respect the 100ms max delay, the dw_hdmi_qp_set_high_tmds_clock_ratio() -+ * helper should be called right before enabling the TMDS Clock and Data in -+ * the PHY configuration callback. -+ */ -+void dw_hdmi_qp_set_high_tmds_clock_ratio(struct dw_hdmi_qp *hdmi, -+ const struct drm_display_info *display) -+{ -+ bool set; -+ -+ if (dw_hdmi_qp_support_scdc(hdmi, display)) { -+ set = (hdmi->pix_clock > HDMI14_MAX_TMDSCLK); -+ drm_scdc_set_high_tmds_clock_ratio(hdmi->curr_conn, set); -+ } -+} -+EXPORT_SYMBOL_GPL(dw_hdmi_qp_set_high_tmds_clock_ratio); -+ -+static void dw_hdmi_qp_write(struct dw_hdmi_qp *hdmi, unsigned int val, -+ int offset) -+{ -+ regmap_write(hdmi->regm, offset, val); -+} -+ -+static unsigned int dw_hdmi_qp_read(struct dw_hdmi_qp *hdmi, int offset) -+{ -+ unsigned int val = 0; -+ -+ regmap_read(hdmi->regm, offset, &val); -+ -+ return val; -+} -+ -+static void dw_hdmi_qp_mod(struct dw_hdmi_qp *hdmi, unsigned int data, -+ unsigned int mask, unsigned int reg) -+{ -+ regmap_update_bits(hdmi->regm, reg, mask, data); -+} -+ -+static int dw_hdmi_qp_i2c_read(struct dw_hdmi_qp *hdmi, -+ unsigned char *buf, unsigned int length) -+{ -+ struct dw_hdmi_qp_i2c *i2c = hdmi->i2c; -+ int stat; -+ -+ if (!i2c->is_regaddr) { -+ dev_dbg(hdmi->dev, "set read register address to 0\n"); -+ i2c->slave_reg = 0x00; -+ i2c->is_regaddr = true; -+ } -+ -+ while (length--) { -+ reinit_completion(&i2c->cmp); -+ -+ dw_hdmi_qp_mod(hdmi, i2c->slave_reg++ << 12, I2CM_ADDR, -+ I2CM_INTERFACE_CONTROL0); -+ -+ if (i2c->is_segment) -+ dw_hdmi_qp_mod(hdmi, I2CM_EXT_READ, I2CM_WR_MASK, -+ I2CM_INTERFACE_CONTROL0); -+ else -+ dw_hdmi_qp_mod(hdmi, I2CM_FM_READ, I2CM_WR_MASK, -+ I2CM_INTERFACE_CONTROL0); -+ -+ stat = wait_for_completion_timeout(&i2c->cmp, HZ / 10); -+ if (!stat) { -+ dev_err(hdmi->dev, "i2c read timed out\n"); -+ dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0); -+ return -EAGAIN; -+ } -+ -+ /* Check for error condition on the bus */ -+ if (i2c->stat & I2CM_NACK_RCVD_IRQ) { -+ dev_err(hdmi->dev, "i2c read error\n"); -+ dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0); -+ return -EIO; -+ } -+ -+ *buf++ = dw_hdmi_qp_read(hdmi, I2CM_INTERFACE_RDDATA_0_3) & 0xff; -+ dw_hdmi_qp_mod(hdmi, 0, I2CM_WR_MASK, I2CM_INTERFACE_CONTROL0); -+ } -+ -+ i2c->is_segment = false; -+ -+ return 0; -+} -+ -+static int dw_hdmi_qp_i2c_write(struct dw_hdmi_qp *hdmi, -+ unsigned char *buf, unsigned int length) -+{ -+ struct dw_hdmi_qp_i2c *i2c = hdmi->i2c; -+ int stat; -+ -+ if (!i2c->is_regaddr) { -+ /* Use the first write byte as register address */ -+ i2c->slave_reg = buf[0]; -+ length--; -+ buf++; -+ i2c->is_regaddr = true; -+ } -+ -+ while (length--) { -+ reinit_completion(&i2c->cmp); -+ -+ dw_hdmi_qp_write(hdmi, *buf++, I2CM_INTERFACE_WRDATA_0_3); -+ dw_hdmi_qp_mod(hdmi, i2c->slave_reg++ << 12, I2CM_ADDR, -+ I2CM_INTERFACE_CONTROL0); -+ dw_hdmi_qp_mod(hdmi, I2CM_FM_WRITE, I2CM_WR_MASK, -+ I2CM_INTERFACE_CONTROL0); -+ -+ stat = wait_for_completion_timeout(&i2c->cmp, HZ / 10); -+ if (!stat) { -+ dev_err(hdmi->dev, "i2c write time out!\n"); -+ dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0); -+ return -EAGAIN; -+ } -+ -+ /* Check for error condition on the bus */ -+ if (i2c->stat & I2CM_NACK_RCVD_IRQ) { -+ dev_err(hdmi->dev, "i2c write nack!\n"); -+ dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0); -+ return -EIO; -+ } -+ -+ dw_hdmi_qp_mod(hdmi, 0, I2CM_WR_MASK, I2CM_INTERFACE_CONTROL0); -+ } -+ -+ return 0; -+} -+ -+static int dw_hdmi_qp_i2c_xfer(struct i2c_adapter *adap, -+ struct i2c_msg *msgs, int num) -+{ -+ struct dw_hdmi_qp *hdmi = i2c_get_adapdata(adap); -+ struct dw_hdmi_qp_i2c *i2c = hdmi->i2c; -+ u8 addr = msgs[0].addr; -+ int i, ret = 0; -+ -+ if (addr == DDC_CI_ADDR) -+ /* -+ * The internal I2C controller does not support the multi-byte -+ * read and write operations needed for DDC/CI. -+ * FIXME: Blacklist the DDC/CI address until we filter out -+ * unsupported I2C operations. -+ */ -+ return -EOPNOTSUPP; -+ -+ for (i = 0; i < num; i++) { -+ if (msgs[i].len == 0) { -+ dev_err(hdmi->dev, -+ "unsupported transfer %d/%d, no data\n", -+ i + 1, num); -+ return -EOPNOTSUPP; -+ } -+ } -+ -+ mutex_lock(&i2c->lock); -+ -+ /* Unmute DONE and ERROR interrupts */ -+ dw_hdmi_qp_mod(hdmi, I2CM_NACK_RCVD_MASK_N | I2CM_OP_DONE_MASK_N, -+ I2CM_NACK_RCVD_MASK_N | I2CM_OP_DONE_MASK_N, -+ MAINUNIT_1_INT_MASK_N); -+ -+ /* Set slave device address taken from the first I2C message */ -+ if (addr == DDC_SEGMENT_ADDR && msgs[0].len == 1) -+ addr = DDC_ADDR; -+ -+ dw_hdmi_qp_mod(hdmi, addr << 5, I2CM_SLVADDR, I2CM_INTERFACE_CONTROL0); -+ -+ /* Set slave device register address on transfer */ -+ i2c->is_regaddr = false; -+ -+ /* Set segment pointer for I2C extended read mode operation */ -+ i2c->is_segment = false; -+ -+ for (i = 0; i < num; i++) { -+ if (msgs[i].addr == DDC_SEGMENT_ADDR && msgs[i].len == 1) { -+ i2c->is_segment = true; -+ dw_hdmi_qp_mod(hdmi, DDC_SEGMENT_ADDR, I2CM_SEG_ADDR, -+ I2CM_INTERFACE_CONTROL1); -+ dw_hdmi_qp_mod(hdmi, *msgs[i].buf << 7, I2CM_SEG_PTR, -+ I2CM_INTERFACE_CONTROL1); -+ } else { -+ if (msgs[i].flags & I2C_M_RD) -+ ret = dw_hdmi_qp_i2c_read(hdmi, msgs[i].buf, -+ msgs[i].len); -+ else -+ ret = dw_hdmi_qp_i2c_write(hdmi, msgs[i].buf, -+ msgs[i].len); -+ } -+ if (ret < 0) -+ break; -+ } -+ -+ if (!ret) -+ ret = num; -+ -+ /* Mute DONE and ERROR interrupts */ -+ dw_hdmi_qp_mod(hdmi, 0, I2CM_OP_DONE_MASK_N | I2CM_NACK_RCVD_MASK_N, -+ MAINUNIT_1_INT_MASK_N); -+ -+ mutex_unlock(&i2c->lock); -+ -+ return ret; -+} -+ -+static u32 dw_hdmi_qp_i2c_func(struct i2c_adapter *adapter) -+{ -+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; -+} -+ -+static const struct i2c_algorithm dw_hdmi_qp_algorithm = { -+ .master_xfer = dw_hdmi_qp_i2c_xfer, -+ .functionality = dw_hdmi_qp_i2c_func, -+}; -+ -+static struct i2c_adapter *dw_hdmi_qp_i2c_adapter(struct dw_hdmi_qp *hdmi) -+{ -+ struct dw_hdmi_qp_i2c *i2c; -+ struct i2c_adapter *adap; -+ int ret; -+ -+ i2c = devm_kzalloc(hdmi->dev, sizeof(*i2c), GFP_KERNEL); -+ if (!i2c) -+ return ERR_PTR(-ENOMEM); -+ -+ mutex_init(&i2c->lock); -+ init_completion(&i2c->cmp); -+ -+ adap = &i2c->adap; -+ adap->owner = THIS_MODULE; -+ adap->dev.parent = hdmi->dev; -+ adap->algo = &dw_hdmi_qp_algorithm; -+ strscpy(adap->name, "DesignWare HDMI QP", sizeof(adap->name)); -+ -+ i2c_set_adapdata(adap, hdmi); -+ -+ ret = devm_i2c_add_adapter(hdmi->dev, adap); -+ if (ret) { -+ dev_warn(hdmi->dev, "cannot add %s I2C adapter\n", adap->name); -+ devm_kfree(hdmi->dev, i2c); -+ return ERR_PTR(ret); -+ } -+ -+ hdmi->i2c = i2c; -+ dev_info(hdmi->dev, "registered %s I2C bus driver\n", adap->name); -+ -+ return adap; -+} -+ -+static int dw_hdmi_qp_config_avi_infoframe(struct dw_hdmi_qp *hdmi, -+ const u8 *buffer, size_t len) -+{ -+ u32 val, i, j; -+ -+ if (len != HDMI_INFOFRAME_SIZE(AVI)) { -+ dev_err(hdmi->dev, "failed to configure avi infoframe\n"); -+ return -EINVAL; -+ } -+ -+ /* -+ * DW HDMI QP IP uses a different byte format from standard AVI info -+ * frames, though generally the bits are in the correct bytes. -+ */ -+ val = buffer[1] << 8 | buffer[2] << 16; -+ dw_hdmi_qp_write(hdmi, val, PKT_AVI_CONTENTS0); -+ -+ for (i = 0; i < 4; i++) { -+ for (j = 0; j < 4; j++) { -+ if (i * 4 + j >= 14) -+ break; -+ if (!j) -+ val = buffer[i * 4 + j + 3]; -+ val |= buffer[i * 4 + j + 3] << (8 * j); -+ } -+ -+ dw_hdmi_qp_write(hdmi, val, PKT_AVI_CONTENTS1 + i * 4); -+ } -+ -+ dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_AVI_FIELDRATE, PKTSCHED_PKT_CONFIG1); -+ -+ dw_hdmi_qp_mod(hdmi, PKTSCHED_AVI_TX_EN | PKTSCHED_GCP_TX_EN, -+ PKTSCHED_AVI_TX_EN | PKTSCHED_GCP_TX_EN, PKTSCHED_PKT_EN); -+ -+ return 0; -+} -+ -+static int dw_hdmi_qp_config_drm_infoframe(struct dw_hdmi_qp *hdmi, -+ const u8 *buffer, size_t len) -+{ -+ u32 val, i; -+ -+ if (len != HDMI_INFOFRAME_SIZE(DRM)) { -+ dev_err(hdmi->dev, "failed to configure drm infoframe\n"); -+ return -EINVAL; -+ } -+ -+ dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_DRMI_TX_EN, PKTSCHED_PKT_EN); -+ -+ val = buffer[1] << 8 | buffer[2] << 16; -+ dw_hdmi_qp_write(hdmi, val, PKT_DRMI_CONTENTS0); -+ -+ for (i = 0; i <= buffer[2]; i++) { -+ if (i % 4 == 0) -+ val = buffer[3 + i]; -+ val |= buffer[3 + i] << ((i % 4) * 8); -+ -+ if ((i % 4 == 3) || i == buffer[2]) -+ dw_hdmi_qp_write(hdmi, val, -+ PKT_DRMI_CONTENTS1 + ((i / 4) * 4)); -+ } -+ -+ dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_DRMI_FIELDRATE, PKTSCHED_PKT_CONFIG1); -+ dw_hdmi_qp_mod(hdmi, PKTSCHED_DRMI_TX_EN, PKTSCHED_DRMI_TX_EN, -+ PKTSCHED_PKT_EN); -+ -+ return 0; -+} -+ -+static void dw_hdmi_qp_setup(struct dw_hdmi_qp *hdmi, -+ struct drm_connector *connector) -+{ -+ bool scramb; -+ u8 ver; -+ -+ if (!connector->display_info.is_hdmi) { -+ dev_dbg(hdmi->dev, "%s DVI mode\n", __func__); -+ -+ dw_hdmi_qp_mod(hdmi, HDCP2_BYPASS, HDCP2_BYPASS, -+ HDCP2LOGIC_CONFIG0); -+ dw_hdmi_qp_mod(hdmi, OPMODE_DVI, OPMODE_DVI, LINK_CONFIG0); -+ -+ return; -+ } -+ -+ dev_dbg(hdmi->dev, "%s HDMI mode\n", __func__); -+ -+ dw_hdmi_qp_mod(hdmi, 0, OPMODE_DVI, LINK_CONFIG0); -+ dw_hdmi_qp_mod(hdmi, HDCP2_BYPASS, HDCP2_BYPASS, HDCP2LOGIC_CONFIG0); -+ -+ scramb = (hdmi->pix_clock > HDMI14_MAX_TMDSCLK); -+ -+ if (dw_hdmi_qp_support_scdc(hdmi, &connector->display_info)) { -+ if (scramb) { -+ drm_scdc_readb(hdmi->bridge.ddc, SCDC_SINK_VERSION, &ver); -+ drm_scdc_writeb(hdmi->bridge.ddc, SCDC_SOURCE_VERSION, -+ min_t(u8, ver, SCDC_MIN_SOURCE_VERSION)); -+ } -+ -+ drm_scdc_set_high_tmds_clock_ratio(connector, scramb); -+ drm_scdc_set_scrambling(connector, scramb); -+ } -+ -+ dw_hdmi_qp_write(hdmi, scramb, SCRAMB_CONFIG0); -+} -+ -+static int dw_hdmi_qp_bridge_atomic_check(struct drm_bridge *bridge, -+ struct drm_bridge_state *bridge_state, -+ struct drm_crtc_state *crtc_state, -+ struct drm_connector_state *conn_state) -+{ -+ struct dw_hdmi_qp *hdmi = bridge->driver_private; -+ int ret; -+ -+ ret = drm_atomic_helper_connector_hdmi_check(conn_state->connector, -+ conn_state->state); -+ if (ret) -+ dev_dbg(hdmi->dev, "%s failed: %d\n", __func__, ret); -+ -+ return ret; -+} -+ -+static void dw_hdmi_qp_bridge_atomic_enable(struct drm_bridge *bridge, -+ struct drm_bridge_state *old_state) -+{ -+ struct dw_hdmi_qp *hdmi = bridge->driver_private; -+ struct drm_atomic_state *state = old_state->base.state; -+ struct drm_connector *connector; -+ struct drm_connector_state *conn_state; -+ -+ connector = drm_atomic_get_new_connector_for_encoder(state, -+ bridge->encoder); -+ conn_state = drm_atomic_get_new_connector_state(state, connector); -+ -+ hdmi->pix_clock = conn_state->hdmi.tmds_char_rate; -+ hdmi->curr_conn = connector; -+ -+ hdmi->phy.ops->init(hdmi, hdmi->phy.data, &connector->display_info); -+ -+ dw_hdmi_qp_setup(hdmi, connector); -+ -+ drm_atomic_helper_connector_hdmi_update_infoframes(connector, state); -+} -+ -+static void dw_hdmi_qp_bridge_atomic_disable(struct drm_bridge *bridge, -+ struct drm_bridge_state *old_state) -+{ -+ struct dw_hdmi_qp *hdmi = bridge->driver_private; -+ -+ hdmi->curr_conn = NULL; -+ hdmi->phy.ops->disable(hdmi, hdmi->phy.data); -+} -+ -+static enum drm_connector_status -+dw_hdmi_qp_bridge_detect(struct drm_bridge *bridge) -+{ -+ struct dw_hdmi_qp *hdmi = bridge->driver_private; -+ -+ return hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data); -+} -+ -+static const struct drm_edid * -+dw_hdmi_qp_bridge_edid_read(struct drm_bridge *bridge, -+ struct drm_connector *connector) -+{ -+ struct dw_hdmi_qp *hdmi = bridge->driver_private; -+ const struct drm_edid *drm_edid; -+ -+ if (!bridge->ddc) -+ return NULL; -+ -+ drm_edid = drm_edid_read_ddc(connector, bridge->ddc); -+ if (!drm_edid) -+ dev_dbg(hdmi->dev, "failed to get edid\n"); -+ -+ return drm_edid; -+} -+ -+static int dw_hdmi_qp_bridge_clear_infoframe(struct drm_bridge *bridge, -+ enum hdmi_infoframe_type type) -+{ -+ struct dw_hdmi_qp *hdmi = bridge->driver_private; -+ -+ switch (type) { -+ case HDMI_INFOFRAME_TYPE_AVI: -+ dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_AVI_TX_EN | PKTSCHED_GCP_TX_EN, -+ PKTSCHED_PKT_EN); -+ break; -+ -+ case HDMI_INFOFRAME_TYPE_DRM: -+ dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_DRMI_TX_EN, PKTSCHED_PKT_EN); -+ break; -+ -+ default: -+ dev_dbg(hdmi->dev, "Unsupported infoframe type %x\n", type); -+ } -+ -+ return 0; -+} -+ -+static int dw_hdmi_qp_bridge_write_infoframe(struct drm_bridge *bridge, -+ enum hdmi_infoframe_type type, -+ const u8 *buffer, size_t len) -+{ -+ struct dw_hdmi_qp *hdmi = bridge->driver_private; -+ -+ dw_hdmi_qp_bridge_clear_infoframe(bridge, type); -+ -+ switch (type) { -+ case HDMI_INFOFRAME_TYPE_AVI: -+ return dw_hdmi_qp_config_avi_infoframe(hdmi, buffer, len); -+ -+ case HDMI_INFOFRAME_TYPE_DRM: -+ return dw_hdmi_qp_config_drm_infoframe(hdmi, buffer, len); -+ -+ default: -+ dev_dbg(hdmi->dev, "Unsupported infoframe type %x\n", type); -+ return 0; -+ } -+} -+ -+static const struct drm_bridge_funcs dw_hdmi_qp_bridge_funcs = { -+ .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, -+ .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, -+ .atomic_reset = drm_atomic_helper_bridge_reset, -+ .atomic_check = dw_hdmi_qp_bridge_atomic_check, -+ .atomic_enable = dw_hdmi_qp_bridge_atomic_enable, -+ .atomic_disable = dw_hdmi_qp_bridge_atomic_disable, -+ .detect = dw_hdmi_qp_bridge_detect, -+ .edid_read = dw_hdmi_qp_bridge_edid_read, -+ .hdmi_clear_infoframe = dw_hdmi_qp_bridge_clear_infoframe, -+ .hdmi_write_infoframe = dw_hdmi_qp_bridge_write_infoframe, -+}; -+ -+static irqreturn_t dw_hdmi_qp_main_hardirq(int irq, void *dev_id) -+{ -+ struct dw_hdmi_qp *hdmi = dev_id; -+ struct dw_hdmi_qp_i2c *i2c = hdmi->i2c; -+ u32 stat; -+ -+ stat = dw_hdmi_qp_read(hdmi, MAINUNIT_1_INT_STATUS); -+ -+ i2c->stat = stat & (I2CM_OP_DONE_IRQ | I2CM_READ_REQUEST_IRQ | -+ I2CM_NACK_RCVD_IRQ); -+ -+ if (i2c->stat) { -+ dw_hdmi_qp_write(hdmi, i2c->stat, MAINUNIT_1_INT_CLEAR); -+ complete(&i2c->cmp); -+ } -+ -+ if (stat) -+ return IRQ_HANDLED; -+ -+ return IRQ_NONE; -+} -+ -+static const struct regmap_config dw_hdmi_qp_regmap_config = { -+ .reg_bits = 32, -+ .val_bits = 32, -+ .reg_stride = 4, -+ .max_register = EARCRX_1_INT_FORCE, -+}; -+ -+static void dw_hdmi_qp_init_hw(struct dw_hdmi_qp *hdmi) -+{ -+ dw_hdmi_qp_write(hdmi, 0, MAINUNIT_0_INT_MASK_N); -+ dw_hdmi_qp_write(hdmi, 0, MAINUNIT_1_INT_MASK_N); -+ dw_hdmi_qp_write(hdmi, 428571429, TIMER_BASE_CONFIG0); -+ -+ /* Software reset */ -+ dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0); -+ -+ dw_hdmi_qp_write(hdmi, 0x085c085c, I2CM_FM_SCL_CONFIG0); -+ -+ dw_hdmi_qp_mod(hdmi, 0, I2CM_FM_EN, I2CM_INTERFACE_CONTROL0); -+ -+ /* Clear DONE and ERROR interrupts */ -+ dw_hdmi_qp_write(hdmi, I2CM_OP_DONE_CLEAR | I2CM_NACK_RCVD_CLEAR, -+ MAINUNIT_1_INT_CLEAR); -+ -+ if (hdmi->phy.ops->setup_hpd) -+ hdmi->phy.ops->setup_hpd(hdmi, hdmi->phy.data); -+} -+ -+struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev, -+ struct drm_encoder *encoder, -+ const struct dw_hdmi_qp_plat_data *plat_data) -+{ -+ struct device *dev = &pdev->dev; -+ struct dw_hdmi_qp *hdmi; -+ void __iomem *regs; -+ int irq, ret; -+ -+ if (!plat_data->phy_ops || !plat_data->phy_ops->init || -+ !plat_data->phy_ops->disable || !plat_data->phy_ops->read_hpd) { -+ dev_err(dev, "Missing platform PHY ops\n"); -+ return ERR_PTR(-ENODEV); -+ } -+ -+ hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL); -+ if (!hdmi) -+ return ERR_PTR(-ENOMEM); -+ -+ hdmi->dev = dev; -+ -+ regs = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(regs)) -+ return regs; -+ -+ hdmi->regm = devm_regmap_init_mmio(dev, regs, &dw_hdmi_qp_regmap_config); -+ if (IS_ERR(hdmi->regm)) { -+ dev_err(dev, "Failed to configure regmap\n"); -+ return ERR_CAST(hdmi->regm); -+ } -+ -+ hdmi->phy.ops = plat_data->phy_ops; -+ hdmi->phy.data =plat_data->phy_data; -+ -+ dw_hdmi_qp_init_hw(hdmi); -+ -+ /* Not handled for now: IRQ0 (AVP), IRQ1 (CEC), IRQ2 (EARC) */ -+ irq = platform_get_irq(pdev, 3); -+ if (irq < 0) -+ return ERR_PTR(irq); -+ -+ ret = devm_request_threaded_irq(dev, irq, -+ dw_hdmi_qp_main_hardirq, NULL, -+ IRQF_SHARED, dev_name(dev), hdmi); -+ if (ret) -+ return ERR_PTR(ret); -+ -+ hdmi->bridge.driver_private = hdmi; -+ hdmi->bridge.funcs = &dw_hdmi_qp_bridge_funcs; -+ hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | -+ DRM_BRIDGE_OP_EDID | -+ DRM_BRIDGE_OP_HDMI | -+ DRM_BRIDGE_OP_HPD; -+ hdmi->bridge.of_node = pdev->dev.of_node; -+ hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA; -+ hdmi->bridge.vendor = "Synopsys"; -+ hdmi->bridge.product = "DW HDMI QP TX"; -+ -+ hdmi->bridge.ddc = dw_hdmi_qp_i2c_adapter(hdmi); -+ if (IS_ERR(hdmi->bridge.ddc)) -+ hdmi->bridge.ddc = NULL; -+ -+ ret = devm_drm_bridge_add(dev, &hdmi->bridge); -+ if (ret) -+ return ERR_PTR(ret); -+ -+ ret = drm_bridge_attach(encoder, &hdmi->bridge, NULL, -+ DRM_BRIDGE_ATTACH_NO_CONNECTOR); -+ if (ret) -+ return ERR_PTR(ret); -+ -+ return hdmi; -+} -+EXPORT_SYMBOL_GPL(dw_hdmi_qp_bind); -+ -+void dw_hdmi_qp_unbind(struct dw_hdmi_qp *hdmi) -+{ -+} -+EXPORT_SYMBOL_GPL(dw_hdmi_qp_unbind); -+ -+void dw_hdmi_qp_resume(struct device *dev, struct dw_hdmi_qp *hdmi) -+{ -+ dw_hdmi_qp_init_hw(hdmi); -+} -+EXPORT_SYMBOL_GPL(dw_hdmi_qp_resume); -+ -+MODULE_AUTHOR("Algea Cao <algea.cao@rock-chips.com>"); -+MODULE_AUTHOR("Cristian Ciocaltea <cristian.ciocaltea@collabora.com>"); -+MODULE_DESCRIPTION("DW HDMI QP transmitter driver"); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("platform:dw-hdmi-qp"); -diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.h -new file mode 100644 -index 000000000000..2115b8ef0bd6 ---- /dev/null -+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.h -@@ -0,0 +1,834 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) Rockchip Electronics Co.Ltd -+ * Author: -+ * Algea Cao <algea.cao@rock-chips.com> -+ */ -+#ifndef __DW_HDMI_QP_H__ -+#define __DW_HDMI_QP_H__ -+ -+#include <linux/bits.h> -+ -+/* Main Unit Registers */ -+#define CORE_ID 0x0 -+#define VER_NUMBER 0x4 -+#define VER_TYPE 0x8 -+#define CONFIG_REG 0xc -+#define CONFIG_CEC BIT(28) -+#define CONFIG_AUD_UD BIT(23) -+#define CORE_TIMESTAMP_HHMM 0x14 -+#define CORE_TIMESTAMP_MMDD 0x18 -+#define CORE_TIMESTAMP_YYYY 0x1c -+/* Reset Manager Registers */ -+#define GLOBAL_SWRESET_REQUEST 0x40 -+#define EARCRX_CMDC_SWINIT_P BIT(27) -+#define AVP_DATAPATH_PACKET_AUDIO_SWINIT_P BIT(10) -+#define GLOBAL_SWDISABLE 0x44 -+#define CEC_SWDISABLE BIT(17) -+#define AVP_DATAPATH_PACKET_AUDIO_SWDISABLE BIT(10) -+#define AVP_DATAPATH_VIDEO_SWDISABLE BIT(6) -+#define RESET_MANAGER_CONFIG0 0x48 -+#define RESET_MANAGER_STATUS0 0x50 -+#define RESET_MANAGER_STATUS1 0x54 -+#define RESET_MANAGER_STATUS2 0x58 -+/* Timer Base Registers */ -+#define TIMER_BASE_CONFIG0 0x80 -+#define TIMER_BASE_STATUS0 0x84 -+/* CMU Registers */ -+#define CMU_CONFIG0 0xa0 -+#define CMU_CONFIG1 0xa4 -+#define CMU_CONFIG2 0xa8 -+#define CMU_CONFIG3 0xac -+#define CMU_STATUS 0xb0 -+#define DISPLAY_CLK_MONITOR 0x3f -+#define DISPLAY_CLK_LOCKED 0X15 -+#define EARC_BPCLK_OFF BIT(9) -+#define AUDCLK_OFF BIT(7) -+#define LINKQPCLK_OFF BIT(5) -+#define VIDQPCLK_OFF BIT(3) -+#define IPI_CLK_OFF BIT(1) -+#define CMU_IPI_CLK_FREQ 0xb4 -+#define CMU_VIDQPCLK_FREQ 0xb8 -+#define CMU_LINKQPCLK_FREQ 0xbc -+#define CMU_AUDQPCLK_FREQ 0xc0 -+#define CMU_EARC_BPCLK_FREQ 0xc4 -+/* I2CM Registers */ -+#define I2CM_SM_SCL_CONFIG0 0xe0 -+#define I2CM_FM_SCL_CONFIG0 0xe4 -+#define I2CM_CONFIG0 0xe8 -+#define I2CM_CONTROL0 0xec -+#define I2CM_STATUS0 0xf0 -+#define I2CM_INTERFACE_CONTROL0 0xf4 -+#define I2CM_ADDR 0xff000 -+#define I2CM_SLVADDR 0xfe0 -+#define I2CM_WR_MASK 0x1e -+#define I2CM_EXT_READ BIT(4) -+#define I2CM_SHORT_READ BIT(3) -+#define I2CM_FM_READ BIT(2) -+#define I2CM_FM_WRITE BIT(1) -+#define I2CM_FM_EN BIT(0) -+#define I2CM_INTERFACE_CONTROL1 0xf8 -+#define I2CM_SEG_PTR 0x7f80 -+#define I2CM_SEG_ADDR 0x7f -+#define I2CM_INTERFACE_WRDATA_0_3 0xfc -+#define I2CM_INTERFACE_WRDATA_4_7 0x100 -+#define I2CM_INTERFACE_WRDATA_8_11 0x104 -+#define I2CM_INTERFACE_WRDATA_12_15 0x108 -+#define I2CM_INTERFACE_RDDATA_0_3 0x10c -+#define I2CM_INTERFACE_RDDATA_4_7 0x110 -+#define I2CM_INTERFACE_RDDATA_8_11 0x114 -+#define I2CM_INTERFACE_RDDATA_12_15 0x118 -+/* SCDC Registers */ -+#define SCDC_CONFIG0 0x140 -+#define SCDC_I2C_FM_EN BIT(12) -+#define SCDC_UPD_FLAGS_AUTO_CLR BIT(6) -+#define SCDC_UPD_FLAGS_POLL_EN BIT(4) -+#define SCDC_CONTROL0 0x148 -+#define SCDC_STATUS0 0x150 -+#define STATUS_UPDATE BIT(0) -+#define FRL_START BIT(4) -+#define FLT_UPDATE BIT(5) -+/* FLT Registers */ -+#define FLT_CONFIG0 0x160 -+#define FLT_CONFIG1 0x164 -+#define FLT_CONFIG2 0x168 -+#define FLT_CONTROL0 0x170 -+/* Main Unit 2 Registers */ -+#define MAINUNIT_STATUS0 0x180 -+/* Video Interface Registers */ -+#define VIDEO_INTERFACE_CONFIG0 0x800 -+#define VIDEO_INTERFACE_CONFIG1 0x804 -+#define VIDEO_INTERFACE_CONFIG2 0x808 -+#define VIDEO_INTERFACE_CONTROL0 0x80c -+#define VIDEO_INTERFACE_STATUS0 0x814 -+/* Video Packing Registers */ -+#define VIDEO_PACKING_CONFIG0 0x81c -+/* Audio Interface Registers */ -+#define AUDIO_INTERFACE_CONFIG0 0x820 -+#define AUD_IF_SEL_MSK 0x3 -+#define AUD_IF_SPDIF 0x2 -+#define AUD_IF_I2S 0x1 -+#define AUD_IF_PAI 0x0 -+#define AUD_FIFO_INIT_ON_OVF_MSK BIT(2) -+#define AUD_FIFO_INIT_ON_OVF_EN BIT(2) -+#define I2S_LINES_EN_MSK GENMASK(7, 4) -+#define I2S_LINES_EN(x) BIT((x) + 4) -+#define I2S_BPCUV_RCV_MSK BIT(12) -+#define I2S_BPCUV_RCV_EN BIT(12) -+#define I2S_BPCUV_RCV_DIS 0 -+#define SPDIF_LINES_EN GENMASK(19, 16) -+#define AUD_FORMAT_MSK GENMASK(26, 24) -+#define AUD_3DOBA (0x7 << 24) -+#define AUD_3DASP (0x6 << 24) -+#define AUD_MSOBA (0x5 << 24) -+#define AUD_MSASP (0x4 << 24) -+#define AUD_HBR (0x3 << 24) -+#define AUD_DST (0x2 << 24) -+#define AUD_OBA (0x1 << 24) -+#define AUD_ASP (0x0 << 24) -+#define AUDIO_INTERFACE_CONFIG1 0x824 -+#define AUDIO_INTERFACE_CONTROL0 0x82c -+#define AUDIO_FIFO_CLR_P BIT(0) -+#define AUDIO_INTERFACE_STATUS0 0x834 -+/* Frame Composer Registers */ -+#define FRAME_COMPOSER_CONFIG0 0x840 -+#define FRAME_COMPOSER_CONFIG1 0x844 -+#define FRAME_COMPOSER_CONFIG2 0x848 -+#define FRAME_COMPOSER_CONFIG3 0x84c -+#define FRAME_COMPOSER_CONFIG4 0x850 -+#define FRAME_COMPOSER_CONFIG5 0x854 -+#define FRAME_COMPOSER_CONFIG6 0x858 -+#define FRAME_COMPOSER_CONFIG7 0x85c -+#define FRAME_COMPOSER_CONFIG8 0x860 -+#define FRAME_COMPOSER_CONFIG9 0x864 -+#define FRAME_COMPOSER_CONTROL0 0x86c -+/* Video Monitor Registers */ -+#define VIDEO_MONITOR_CONFIG0 0x880 -+#define VIDEO_MONITOR_STATUS0 0x884 -+#define VIDEO_MONITOR_STATUS1 0x888 -+#define VIDEO_MONITOR_STATUS2 0x88c -+#define VIDEO_MONITOR_STATUS3 0x890 -+#define VIDEO_MONITOR_STATUS4 0x894 -+#define VIDEO_MONITOR_STATUS5 0x898 -+#define VIDEO_MONITOR_STATUS6 0x89c -+/* HDCP2 Logic Registers */ -+#define HDCP2LOGIC_CONFIG0 0x8e0 -+#define HDCP2_BYPASS BIT(0) -+#define HDCP2LOGIC_ESM_GPIO_IN 0x8e4 -+#define HDCP2LOGIC_ESM_GPIO_OUT 0x8e8 -+/* HDCP14 Registers */ -+#define HDCP14_CONFIG0 0x900 -+#define HDCP14_CONFIG1 0x904 -+#define HDCP14_CONFIG2 0x908 -+#define HDCP14_CONFIG3 0x90c -+#define HDCP14_KEY_SEED 0x914 -+#define HDCP14_KEY_H 0x918 -+#define HDCP14_KEY_L 0x91c -+#define HDCP14_KEY_STATUS 0x920 -+#define HDCP14_AKSV_H 0x924 -+#define HDCP14_AKSV_L 0x928 -+#define HDCP14_AN_H 0x92c -+#define HDCP14_AN_L 0x930 -+#define HDCP14_STATUS0 0x934 -+#define HDCP14_STATUS1 0x938 -+/* Scrambler Registers */ -+#define SCRAMB_CONFIG0 0x960 -+/* Video Configuration Registers */ -+#define LINK_CONFIG0 0x968 -+#define OPMODE_FRL_4LANES BIT(8) -+#define OPMODE_DVI BIT(4) -+#define OPMODE_FRL BIT(0) -+/* TMDS FIFO Registers */ -+#define TMDS_FIFO_CONFIG0 0x970 -+#define TMDS_FIFO_CONTROL0 0x974 -+/* FRL RSFEC Registers */ -+#define FRL_RSFEC_CONFIG0 0xa20 -+#define FRL_RSFEC_STATUS0 0xa30 -+/* FRL Packetizer Registers */ -+#define FRL_PKTZ_CONFIG0 0xa40 -+#define FRL_PKTZ_CONTROL0 0xa44 -+#define FRL_PKTZ_CONTROL1 0xa50 -+#define FRL_PKTZ_STATUS1 0xa54 -+/* Packet Scheduler Registers */ -+#define PKTSCHED_CONFIG0 0xa80 -+#define PKTSCHED_PRQUEUE0_CONFIG0 0xa84 -+#define PKTSCHED_PRQUEUE1_CONFIG0 0xa88 -+#define PKTSCHED_PRQUEUE2_CONFIG0 0xa8c -+#define PKTSCHED_PRQUEUE2_CONFIG1 0xa90 -+#define PKTSCHED_PRQUEUE2_CONFIG2 0xa94 -+#define PKTSCHED_PKT_CONFIG0 0xa98 -+#define PKTSCHED_PKT_CONFIG1 0xa9c -+#define PKTSCHED_DRMI_FIELDRATE BIT(13) -+#define PKTSCHED_AVI_FIELDRATE BIT(12) -+#define PKTSCHED_PKT_CONFIG2 0xaa0 -+#define PKTSCHED_PKT_CONFIG3 0xaa4 -+#define PKTSCHED_PKT_EN 0xaa8 -+#define PKTSCHED_DRMI_TX_EN BIT(17) -+#define PKTSCHED_AUDI_TX_EN BIT(15) -+#define PKTSCHED_AVI_TX_EN BIT(13) -+#define PKTSCHED_EMP_CVTEM_TX_EN BIT(10) -+#define PKTSCHED_AMD_TX_EN BIT(8) -+#define PKTSCHED_GCP_TX_EN BIT(3) -+#define PKTSCHED_AUDS_TX_EN BIT(2) -+#define PKTSCHED_ACR_TX_EN BIT(1) -+#define PKTSCHED_NULL_TX_EN BIT(0) -+#define PKTSCHED_PKT_CONTROL0 0xaac -+#define PKTSCHED_PKT_SEND 0xab0 -+#define PKTSCHED_PKT_STATUS0 0xab4 -+#define PKTSCHED_PKT_STATUS1 0xab8 -+#define PKT_NULL_CONTENTS0 0xb00 -+#define PKT_NULL_CONTENTS1 0xb04 -+#define PKT_NULL_CONTENTS2 0xb08 -+#define PKT_NULL_CONTENTS3 0xb0c -+#define PKT_NULL_CONTENTS4 0xb10 -+#define PKT_NULL_CONTENTS5 0xb14 -+#define PKT_NULL_CONTENTS6 0xb18 -+#define PKT_NULL_CONTENTS7 0xb1c -+#define PKT_ACP_CONTENTS0 0xb20 -+#define PKT_ACP_CONTENTS1 0xb24 -+#define PKT_ACP_CONTENTS2 0xb28 -+#define PKT_ACP_CONTENTS3 0xb2c -+#define PKT_ACP_CONTENTS4 0xb30 -+#define PKT_ACP_CONTENTS5 0xb34 -+#define PKT_ACP_CONTENTS6 0xb38 -+#define PKT_ACP_CONTENTS7 0xb3c -+#define PKT_ISRC1_CONTENTS0 0xb40 -+#define PKT_ISRC1_CONTENTS1 0xb44 -+#define PKT_ISRC1_CONTENTS2 0xb48 -+#define PKT_ISRC1_CONTENTS3 0xb4c -+#define PKT_ISRC1_CONTENTS4 0xb50 -+#define PKT_ISRC1_CONTENTS5 0xb54 -+#define PKT_ISRC1_CONTENTS6 0xb58 -+#define PKT_ISRC1_CONTENTS7 0xb5c -+#define PKT_ISRC2_CONTENTS0 0xb60 -+#define PKT_ISRC2_CONTENTS1 0xb64 -+#define PKT_ISRC2_CONTENTS2 0xb68 -+#define PKT_ISRC2_CONTENTS3 0xb6c -+#define PKT_ISRC2_CONTENTS4 0xb70 -+#define PKT_ISRC2_CONTENTS5 0xb74 -+#define PKT_ISRC2_CONTENTS6 0xb78 -+#define PKT_ISRC2_CONTENTS7 0xb7c -+#define PKT_GMD_CONTENTS0 0xb80 -+#define PKT_GMD_CONTENTS1 0xb84 -+#define PKT_GMD_CONTENTS2 0xb88 -+#define PKT_GMD_CONTENTS3 0xb8c -+#define PKT_GMD_CONTENTS4 0xb90 -+#define PKT_GMD_CONTENTS5 0xb94 -+#define PKT_GMD_CONTENTS6 0xb98 -+#define PKT_GMD_CONTENTS7 0xb9c -+#define PKT_AMD_CONTENTS0 0xba0 -+#define PKT_AMD_CONTENTS1 0xba4 -+#define PKT_AMD_CONTENTS2 0xba8 -+#define PKT_AMD_CONTENTS3 0xbac -+#define PKT_AMD_CONTENTS4 0xbb0 -+#define PKT_AMD_CONTENTS5 0xbb4 -+#define PKT_AMD_CONTENTS6 0xbb8 -+#define PKT_AMD_CONTENTS7 0xbbc -+#define PKT_VSI_CONTENTS0 0xbc0 -+#define PKT_VSI_CONTENTS1 0xbc4 -+#define PKT_VSI_CONTENTS2 0xbc8 -+#define PKT_VSI_CONTENTS3 0xbcc -+#define PKT_VSI_CONTENTS4 0xbd0 -+#define PKT_VSI_CONTENTS5 0xbd4 -+#define PKT_VSI_CONTENTS6 0xbd8 -+#define PKT_VSI_CONTENTS7 0xbdc -+#define PKT_AVI_CONTENTS0 0xbe0 -+#define HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT BIT(4) -+#define HDMI_FC_AVICONF0_BAR_DATA_VERT_BAR 0x04 -+#define HDMI_FC_AVICONF0_BAR_DATA_HORIZ_BAR 0x08 -+#define HDMI_FC_AVICONF2_IT_CONTENT_VALID 0x80 -+#define PKT_AVI_CONTENTS1 0xbe4 -+#define PKT_AVI_CONTENTS2 0xbe8 -+#define PKT_AVI_CONTENTS3 0xbec -+#define PKT_AVI_CONTENTS4 0xbf0 -+#define PKT_AVI_CONTENTS5 0xbf4 -+#define PKT_AVI_CONTENTS6 0xbf8 -+#define PKT_AVI_CONTENTS7 0xbfc -+#define PKT_SPDI_CONTENTS0 0xc00 -+#define PKT_SPDI_CONTENTS1 0xc04 -+#define PKT_SPDI_CONTENTS2 0xc08 -+#define PKT_SPDI_CONTENTS3 0xc0c -+#define PKT_SPDI_CONTENTS4 0xc10 -+#define PKT_SPDI_CONTENTS5 0xc14 -+#define PKT_SPDI_CONTENTS6 0xc18 -+#define PKT_SPDI_CONTENTS7 0xc1c -+#define PKT_AUDI_CONTENTS0 0xc20 -+#define PKT_AUDI_CONTENTS1 0xc24 -+#define PKT_AUDI_CONTENTS2 0xc28 -+#define PKT_AUDI_CONTENTS3 0xc2c -+#define PKT_AUDI_CONTENTS4 0xc30 -+#define PKT_AUDI_CONTENTS5 0xc34 -+#define PKT_AUDI_CONTENTS6 0xc38 -+#define PKT_AUDI_CONTENTS7 0xc3c -+#define PKT_NVI_CONTENTS0 0xc40 -+#define PKT_NVI_CONTENTS1 0xc44 -+#define PKT_NVI_CONTENTS2 0xc48 -+#define PKT_NVI_CONTENTS3 0xc4c -+#define PKT_NVI_CONTENTS4 0xc50 -+#define PKT_NVI_CONTENTS5 0xc54 -+#define PKT_NVI_CONTENTS6 0xc58 -+#define PKT_NVI_CONTENTS7 0xc5c -+#define PKT_DRMI_CONTENTS0 0xc60 -+#define PKT_DRMI_CONTENTS1 0xc64 -+#define PKT_DRMI_CONTENTS2 0xc68 -+#define PKT_DRMI_CONTENTS3 0xc6c -+#define PKT_DRMI_CONTENTS4 0xc70 -+#define PKT_DRMI_CONTENTS5 0xc74 -+#define PKT_DRMI_CONTENTS6 0xc78 -+#define PKT_DRMI_CONTENTS7 0xc7c -+#define PKT_GHDMI1_CONTENTS0 0xc80 -+#define PKT_GHDMI1_CONTENTS1 0xc84 -+#define PKT_GHDMI1_CONTENTS2 0xc88 -+#define PKT_GHDMI1_CONTENTS3 0xc8c -+#define PKT_GHDMI1_CONTENTS4 0xc90 -+#define PKT_GHDMI1_CONTENTS5 0xc94 -+#define PKT_GHDMI1_CONTENTS6 0xc98 -+#define PKT_GHDMI1_CONTENTS7 0xc9c -+#define PKT_GHDMI2_CONTENTS0 0xca0 -+#define PKT_GHDMI2_CONTENTS1 0xca4 -+#define PKT_GHDMI2_CONTENTS2 0xca8 -+#define PKT_GHDMI2_CONTENTS3 0xcac -+#define PKT_GHDMI2_CONTENTS4 0xcb0 -+#define PKT_GHDMI2_CONTENTS5 0xcb4 -+#define PKT_GHDMI2_CONTENTS6 0xcb8 -+#define PKT_GHDMI2_CONTENTS7 0xcbc -+/* EMP Packetizer Registers */ -+#define PKT_EMP_CONFIG0 0xce0 -+#define PKT_EMP_CONTROL0 0xcec -+#define PKT_EMP_CONTROL1 0xcf0 -+#define PKT_EMP_CONTROL2 0xcf4 -+#define PKT_EMP_VTEM_CONTENTS0 0xd00 -+#define PKT_EMP_VTEM_CONTENTS1 0xd04 -+#define PKT_EMP_VTEM_CONTENTS2 0xd08 -+#define PKT_EMP_VTEM_CONTENTS3 0xd0c -+#define PKT_EMP_VTEM_CONTENTS4 0xd10 -+#define PKT_EMP_VTEM_CONTENTS5 0xd14 -+#define PKT_EMP_VTEM_CONTENTS6 0xd18 -+#define PKT_EMP_VTEM_CONTENTS7 0xd1c -+#define PKT0_EMP_CVTEM_CONTENTS0 0xd20 -+#define PKT0_EMP_CVTEM_CONTENTS1 0xd24 -+#define PKT0_EMP_CVTEM_CONTENTS2 0xd28 -+#define PKT0_EMP_CVTEM_CONTENTS3 0xd2c -+#define PKT0_EMP_CVTEM_CONTENTS4 0xd30 -+#define PKT0_EMP_CVTEM_CONTENTS5 0xd34 -+#define PKT0_EMP_CVTEM_CONTENTS6 0xd38 -+#define PKT0_EMP_CVTEM_CONTENTS7 0xd3c -+#define PKT1_EMP_CVTEM_CONTENTS0 0xd40 -+#define PKT1_EMP_CVTEM_CONTENTS1 0xd44 -+#define PKT1_EMP_CVTEM_CONTENTS2 0xd48 -+#define PKT1_EMP_CVTEM_CONTENTS3 0xd4c -+#define PKT1_EMP_CVTEM_CONTENTS4 0xd50 -+#define PKT1_EMP_CVTEM_CONTENTS5 0xd54 -+#define PKT1_EMP_CVTEM_CONTENTS6 0xd58 -+#define PKT1_EMP_CVTEM_CONTENTS7 0xd5c -+#define PKT2_EMP_CVTEM_CONTENTS0 0xd60 -+#define PKT2_EMP_CVTEM_CONTENTS1 0xd64 -+#define PKT2_EMP_CVTEM_CONTENTS2 0xd68 -+#define PKT2_EMP_CVTEM_CONTENTS3 0xd6c -+#define PKT2_EMP_CVTEM_CONTENTS4 0xd70 -+#define PKT2_EMP_CVTEM_CONTENTS5 0xd74 -+#define PKT2_EMP_CVTEM_CONTENTS6 0xd78 -+#define PKT2_EMP_CVTEM_CONTENTS7 0xd7c -+#define PKT3_EMP_CVTEM_CONTENTS0 0xd80 -+#define PKT3_EMP_CVTEM_CONTENTS1 0xd84 -+#define PKT3_EMP_CVTEM_CONTENTS2 0xd88 -+#define PKT3_EMP_CVTEM_CONTENTS3 0xd8c -+#define PKT3_EMP_CVTEM_CONTENTS4 0xd90 -+#define PKT3_EMP_CVTEM_CONTENTS5 0xd94 -+#define PKT3_EMP_CVTEM_CONTENTS6 0xd98 -+#define PKT3_EMP_CVTEM_CONTENTS7 0xd9c -+#define PKT4_EMP_CVTEM_CONTENTS0 0xda0 -+#define PKT4_EMP_CVTEM_CONTENTS1 0xda4 -+#define PKT4_EMP_CVTEM_CONTENTS2 0xda8 -+#define PKT4_EMP_CVTEM_CONTENTS3 0xdac -+#define PKT4_EMP_CVTEM_CONTENTS4 0xdb0 -+#define PKT4_EMP_CVTEM_CONTENTS5 0xdb4 -+#define PKT4_EMP_CVTEM_CONTENTS6 0xdb8 -+#define PKT4_EMP_CVTEM_CONTENTS7 0xdbc -+#define PKT5_EMP_CVTEM_CONTENTS0 0xdc0 -+#define PKT5_EMP_CVTEM_CONTENTS1 0xdc4 -+#define PKT5_EMP_CVTEM_CONTENTS2 0xdc8 -+#define PKT5_EMP_CVTEM_CONTENTS3 0xdcc -+#define PKT5_EMP_CVTEM_CONTENTS4 0xdd0 -+#define PKT5_EMP_CVTEM_CONTENTS5 0xdd4 -+#define PKT5_EMP_CVTEM_CONTENTS6 0xdd8 -+#define PKT5_EMP_CVTEM_CONTENTS7 0xddc -+/* Audio Packetizer Registers */ -+#define AUDPKT_CONTROL0 0xe20 -+#define AUDPKT_PBIT_FORCE_EN_MASK BIT(12) -+#define AUDPKT_PBIT_FORCE_EN BIT(12) -+#define AUDPKT_CHSTATUS_OVR_EN_MASK BIT(0) -+#define AUDPKT_CHSTATUS_OVR_EN BIT(0) -+#define AUDPKT_CONTROL1 0xe24 -+#define AUDPKT_ACR_CONTROL0 0xe40 -+#define AUDPKT_ACR_N_VALUE 0xfffff -+#define AUDPKT_ACR_CONTROL1 0xe44 -+#define AUDPKT_ACR_CTS_OVR_VAL_MSK GENMASK(23, 4) -+#define AUDPKT_ACR_CTS_OVR_VAL(x) ((x) << 4) -+#define AUDPKT_ACR_CTS_OVR_EN_MSK BIT(1) -+#define AUDPKT_ACR_CTS_OVR_EN BIT(1) -+#define AUDPKT_ACR_STATUS0 0xe4c -+#define AUDPKT_CHSTATUS_OVR0 0xe60 -+#define AUDPKT_CHSTATUS_OVR1 0xe64 -+/* IEC60958 Byte 3: Sampleing frenuency Bits 24 to 27 */ -+#define AUDPKT_CHSTATUS_SR_MASK GENMASK(3, 0) -+#define AUDPKT_CHSTATUS_SR_22050 0x4 -+#define AUDPKT_CHSTATUS_SR_24000 0x6 -+#define AUDPKT_CHSTATUS_SR_32000 0x3 -+#define AUDPKT_CHSTATUS_SR_44100 0x0 -+#define AUDPKT_CHSTATUS_SR_48000 0x2 -+#define AUDPKT_CHSTATUS_SR_88200 0x8 -+#define AUDPKT_CHSTATUS_SR_96000 0xa -+#define AUDPKT_CHSTATUS_SR_176400 0xc -+#define AUDPKT_CHSTATUS_SR_192000 0xe -+#define AUDPKT_CHSTATUS_SR_768000 0x9 -+#define AUDPKT_CHSTATUS_SR_NOT_INDICATED 0x1 -+/* IEC60958 Byte 4: Original Sampleing frenuency Bits 36 to 39 */ -+#define AUDPKT_CHSTATUS_0SR_MASK GENMASK(15, 12) -+#define AUDPKT_CHSTATUS_OSR_8000 0x6 -+#define AUDPKT_CHSTATUS_OSR_11025 0xa -+#define AUDPKT_CHSTATUS_OSR_12000 0x2 -+#define AUDPKT_CHSTATUS_OSR_16000 0x8 -+#define AUDPKT_CHSTATUS_OSR_22050 0xb -+#define AUDPKT_CHSTATUS_OSR_24000 0x9 -+#define AUDPKT_CHSTATUS_OSR_32000 0xc -+#define AUDPKT_CHSTATUS_OSR_44100 0xf -+#define AUDPKT_CHSTATUS_OSR_48000 0xd -+#define AUDPKT_CHSTATUS_OSR_88200 0x7 -+#define AUDPKT_CHSTATUS_OSR_96000 0x5 -+#define AUDPKT_CHSTATUS_OSR_176400 0x3 -+#define AUDPKT_CHSTATUS_OSR_192000 0x1 -+#define AUDPKT_CHSTATUS_OSR_NOT_INDICATED 0x0 -+#define AUDPKT_CHSTATUS_OVR2 0xe68 -+#define AUDPKT_CHSTATUS_OVR3 0xe6c -+#define AUDPKT_CHSTATUS_OVR4 0xe70 -+#define AUDPKT_CHSTATUS_OVR5 0xe74 -+#define AUDPKT_CHSTATUS_OVR6 0xe78 -+#define AUDPKT_CHSTATUS_OVR7 0xe7c -+#define AUDPKT_CHSTATUS_OVR8 0xe80 -+#define AUDPKT_CHSTATUS_OVR9 0xe84 -+#define AUDPKT_CHSTATUS_OVR10 0xe88 -+#define AUDPKT_CHSTATUS_OVR11 0xe8c -+#define AUDPKT_CHSTATUS_OVR12 0xe90 -+#define AUDPKT_CHSTATUS_OVR13 0xe94 -+#define AUDPKT_CHSTATUS_OVR14 0xe98 -+#define AUDPKT_USRDATA_OVR_MSG_GENERIC0 0xea0 -+#define AUDPKT_USRDATA_OVR_MSG_GENERIC1 0xea4 -+#define AUDPKT_USRDATA_OVR_MSG_GENERIC2 0xea8 -+#define AUDPKT_USRDATA_OVR_MSG_GENERIC3 0xeac -+#define AUDPKT_USRDATA_OVR_MSG_GENERIC4 0xeb0 -+#define AUDPKT_USRDATA_OVR_MSG_GENERIC5 0xeb4 -+#define AUDPKT_USRDATA_OVR_MSG_GENERIC6 0xeb8 -+#define AUDPKT_USRDATA_OVR_MSG_GENERIC7 0xebc -+#define AUDPKT_USRDATA_OVR_MSG_GENERIC8 0xec0 -+#define AUDPKT_USRDATA_OVR_MSG_GENERIC9 0xec4 -+#define AUDPKT_USRDATA_OVR_MSG_GENERIC10 0xec8 -+#define AUDPKT_USRDATA_OVR_MSG_GENERIC11 0xecc -+#define AUDPKT_USRDATA_OVR_MSG_GENERIC12 0xed0 -+#define AUDPKT_USRDATA_OVR_MSG_GENERIC13 0xed4 -+#define AUDPKT_USRDATA_OVR_MSG_GENERIC14 0xed8 -+#define AUDPKT_USRDATA_OVR_MSG_GENERIC15 0xedc -+#define AUDPKT_USRDATA_OVR_MSG_GENERIC16 0xee0 -+#define AUDPKT_USRDATA_OVR_MSG_GENERIC17 0xee4 -+#define AUDPKT_USRDATA_OVR_MSG_GENERIC18 0xee8 -+#define AUDPKT_USRDATA_OVR_MSG_GENERIC19 0xeec -+#define AUDPKT_USRDATA_OVR_MSG_GENERIC20 0xef0 -+#define AUDPKT_USRDATA_OVR_MSG_GENERIC21 0xef4 -+#define AUDPKT_USRDATA_OVR_MSG_GENERIC22 0xef8 -+#define AUDPKT_USRDATA_OVR_MSG_GENERIC23 0xefc -+#define AUDPKT_USRDATA_OVR_MSG_GENERIC24 0xf00 -+#define AUDPKT_USRDATA_OVR_MSG_GENERIC25 0xf04 -+#define AUDPKT_USRDATA_OVR_MSG_GENERIC26 0xf08 -+#define AUDPKT_USRDATA_OVR_MSG_GENERIC27 0xf0c -+#define AUDPKT_USRDATA_OVR_MSG_GENERIC28 0xf10 -+#define AUDPKT_USRDATA_OVR_MSG_GENERIC29 0xf14 -+#define AUDPKT_USRDATA_OVR_MSG_GENERIC30 0xf18 -+#define AUDPKT_USRDATA_OVR_MSG_GENERIC31 0xf1c -+#define AUDPKT_USRDATA_OVR_MSG_GENERIC32 0xf20 -+#define AUDPKT_VBIT_OVR0 0xf24 -+/* CEC Registers */ -+#define CEC_TX_CONTROL 0x1000 -+#define CEC_STATUS 0x1004 -+#define CEC_CONFIG 0x1008 -+#define CEC_ADDR 0x100c -+#define CEC_TX_COUNT 0x1020 -+#define CEC_TX_DATA3_0 0x1024 -+#define CEC_TX_DATA7_4 0x1028 -+#define CEC_TX_DATA11_8 0x102c -+#define CEC_TX_DATA15_12 0x1030 -+#define CEC_RX_COUNT_STATUS 0x1040 -+#define CEC_RX_DATA3_0 0x1044 -+#define CEC_RX_DATA7_4 0x1048 -+#define CEC_RX_DATA11_8 0x104c -+#define CEC_RX_DATA15_12 0x1050 -+#define CEC_LOCK_CONTROL 0x1054 -+#define CEC_RXQUAL_BITTIME_CONFIG 0x1060 -+#define CEC_RX_BITTIME_CONFIG 0x1064 -+#define CEC_TX_BITTIME_CONFIG 0x1068 -+/* eARC RX CMDC Registers */ -+#define EARCRX_CMDC_CONFIG0 0x1800 -+#define EARCRX_XACTREAD_STOP_CFG BIT(26) -+#define EARCRX_XACTREAD_RETRY_CFG BIT(25) -+#define EARCRX_CMDC_DSCVR_EARCVALID0_TO_DISC1 BIT(24) -+#define EARCRX_CMDC_XACT_RESTART_EN BIT(18) -+#define EARCRX_CMDC_CONFIG1 0x1804 -+#define EARCRX_CMDC_CONTROL 0x1808 -+#define EARCRX_CMDC_HEARTBEAT_LOSS_EN BIT(4) -+#define EARCRX_CMDC_DISCOVERY_EN BIT(3) -+#define EARCRX_CONNECTOR_HPD BIT(1) -+#define EARCRX_CMDC_WHITELIST0_CONFIG 0x180c -+#define EARCRX_CMDC_WHITELIST1_CONFIG 0x1810 -+#define EARCRX_CMDC_WHITELIST2_CONFIG 0x1814 -+#define EARCRX_CMDC_WHITELIST3_CONFIG 0x1818 -+#define EARCRX_CMDC_STATUS 0x181c -+#define EARCRX_CMDC_XACT_INFO 0x1820 -+#define EARCRX_CMDC_XACT_ACTION 0x1824 -+#define EARCRX_CMDC_HEARTBEAT_RXSTAT_SE 0x1828 -+#define EARCRX_CMDC_HEARTBEAT_STATUS 0x182c -+#define EARCRX_CMDC_XACT_WR0 0x1840 -+#define EARCRX_CMDC_XACT_WR1 0x1844 -+#define EARCRX_CMDC_XACT_WR2 0x1848 -+#define EARCRX_CMDC_XACT_WR3 0x184c -+#define EARCRX_CMDC_XACT_WR4 0x1850 -+#define EARCRX_CMDC_XACT_WR5 0x1854 -+#define EARCRX_CMDC_XACT_WR6 0x1858 -+#define EARCRX_CMDC_XACT_WR7 0x185c -+#define EARCRX_CMDC_XACT_WR8 0x1860 -+#define EARCRX_CMDC_XACT_WR9 0x1864 -+#define EARCRX_CMDC_XACT_WR10 0x1868 -+#define EARCRX_CMDC_XACT_WR11 0x186c -+#define EARCRX_CMDC_XACT_WR12 0x1870 -+#define EARCRX_CMDC_XACT_WR13 0x1874 -+#define EARCRX_CMDC_XACT_WR14 0x1878 -+#define EARCRX_CMDC_XACT_WR15 0x187c -+#define EARCRX_CMDC_XACT_WR16 0x1880 -+#define EARCRX_CMDC_XACT_WR17 0x1884 -+#define EARCRX_CMDC_XACT_WR18 0x1888 -+#define EARCRX_CMDC_XACT_WR19 0x188c -+#define EARCRX_CMDC_XACT_WR20 0x1890 -+#define EARCRX_CMDC_XACT_WR21 0x1894 -+#define EARCRX_CMDC_XACT_WR22 0x1898 -+#define EARCRX_CMDC_XACT_WR23 0x189c -+#define EARCRX_CMDC_XACT_WR24 0x18a0 -+#define EARCRX_CMDC_XACT_WR25 0x18a4 -+#define EARCRX_CMDC_XACT_WR26 0x18a8 -+#define EARCRX_CMDC_XACT_WR27 0x18ac -+#define EARCRX_CMDC_XACT_WR28 0x18b0 -+#define EARCRX_CMDC_XACT_WR29 0x18b4 -+#define EARCRX_CMDC_XACT_WR30 0x18b8 -+#define EARCRX_CMDC_XACT_WR31 0x18bc -+#define EARCRX_CMDC_XACT_WR32 0x18c0 -+#define EARCRX_CMDC_XACT_WR33 0x18c4 -+#define EARCRX_CMDC_XACT_WR34 0x18c8 -+#define EARCRX_CMDC_XACT_WR35 0x18cc -+#define EARCRX_CMDC_XACT_WR36 0x18d0 -+#define EARCRX_CMDC_XACT_WR37 0x18d4 -+#define EARCRX_CMDC_XACT_WR38 0x18d8 -+#define EARCRX_CMDC_XACT_WR39 0x18dc -+#define EARCRX_CMDC_XACT_WR40 0x18e0 -+#define EARCRX_CMDC_XACT_WR41 0x18e4 -+#define EARCRX_CMDC_XACT_WR42 0x18e8 -+#define EARCRX_CMDC_XACT_WR43 0x18ec -+#define EARCRX_CMDC_XACT_WR44 0x18f0 -+#define EARCRX_CMDC_XACT_WR45 0x18f4 -+#define EARCRX_CMDC_XACT_WR46 0x18f8 -+#define EARCRX_CMDC_XACT_WR47 0x18fc -+#define EARCRX_CMDC_XACT_WR48 0x1900 -+#define EARCRX_CMDC_XACT_WR49 0x1904 -+#define EARCRX_CMDC_XACT_WR50 0x1908 -+#define EARCRX_CMDC_XACT_WR51 0x190c -+#define EARCRX_CMDC_XACT_WR52 0x1910 -+#define EARCRX_CMDC_XACT_WR53 0x1914 -+#define EARCRX_CMDC_XACT_WR54 0x1918 -+#define EARCRX_CMDC_XACT_WR55 0x191c -+#define EARCRX_CMDC_XACT_WR56 0x1920 -+#define EARCRX_CMDC_XACT_WR57 0x1924 -+#define EARCRX_CMDC_XACT_WR58 0x1928 -+#define EARCRX_CMDC_XACT_WR59 0x192c -+#define EARCRX_CMDC_XACT_WR60 0x1930 -+#define EARCRX_CMDC_XACT_WR61 0x1934 -+#define EARCRX_CMDC_XACT_WR62 0x1938 -+#define EARCRX_CMDC_XACT_WR63 0x193c -+#define EARCRX_CMDC_XACT_WR64 0x1940 -+#define EARCRX_CMDC_XACT_RD0 0x1960 -+#define EARCRX_CMDC_XACT_RD1 0x1964 -+#define EARCRX_CMDC_XACT_RD2 0x1968 -+#define EARCRX_CMDC_XACT_RD3 0x196c -+#define EARCRX_CMDC_XACT_RD4 0x1970 -+#define EARCRX_CMDC_XACT_RD5 0x1974 -+#define EARCRX_CMDC_XACT_RD6 0x1978 -+#define EARCRX_CMDC_XACT_RD7 0x197c -+#define EARCRX_CMDC_XACT_RD8 0x1980 -+#define EARCRX_CMDC_XACT_RD9 0x1984 -+#define EARCRX_CMDC_XACT_RD10 0x1988 -+#define EARCRX_CMDC_XACT_RD11 0x198c -+#define EARCRX_CMDC_XACT_RD12 0x1990 -+#define EARCRX_CMDC_XACT_RD13 0x1994 -+#define EARCRX_CMDC_XACT_RD14 0x1998 -+#define EARCRX_CMDC_XACT_RD15 0x199c -+#define EARCRX_CMDC_XACT_RD16 0x19a0 -+#define EARCRX_CMDC_XACT_RD17 0x19a4 -+#define EARCRX_CMDC_XACT_RD18 0x19a8 -+#define EARCRX_CMDC_XACT_RD19 0x19ac -+#define EARCRX_CMDC_XACT_RD20 0x19b0 -+#define EARCRX_CMDC_XACT_RD21 0x19b4 -+#define EARCRX_CMDC_XACT_RD22 0x19b8 -+#define EARCRX_CMDC_XACT_RD23 0x19bc -+#define EARCRX_CMDC_XACT_RD24 0x19c0 -+#define EARCRX_CMDC_XACT_RD25 0x19c4 -+#define EARCRX_CMDC_XACT_RD26 0x19c8 -+#define EARCRX_CMDC_XACT_RD27 0x19cc -+#define EARCRX_CMDC_XACT_RD28 0x19d0 -+#define EARCRX_CMDC_XACT_RD29 0x19d4 -+#define EARCRX_CMDC_XACT_RD30 0x19d8 -+#define EARCRX_CMDC_XACT_RD31 0x19dc -+#define EARCRX_CMDC_XACT_RD32 0x19e0 -+#define EARCRX_CMDC_XACT_RD33 0x19e4 -+#define EARCRX_CMDC_XACT_RD34 0x19e8 -+#define EARCRX_CMDC_XACT_RD35 0x19ec -+#define EARCRX_CMDC_XACT_RD36 0x19f0 -+#define EARCRX_CMDC_XACT_RD37 0x19f4 -+#define EARCRX_CMDC_XACT_RD38 0x19f8 -+#define EARCRX_CMDC_XACT_RD39 0x19fc -+#define EARCRX_CMDC_XACT_RD40 0x1a00 -+#define EARCRX_CMDC_XACT_RD41 0x1a04 -+#define EARCRX_CMDC_XACT_RD42 0x1a08 -+#define EARCRX_CMDC_XACT_RD43 0x1a0c -+#define EARCRX_CMDC_XACT_RD44 0x1a10 -+#define EARCRX_CMDC_XACT_RD45 0x1a14 -+#define EARCRX_CMDC_XACT_RD46 0x1a18 -+#define EARCRX_CMDC_XACT_RD47 0x1a1c -+#define EARCRX_CMDC_XACT_RD48 0x1a20 -+#define EARCRX_CMDC_XACT_RD49 0x1a24 -+#define EARCRX_CMDC_XACT_RD50 0x1a28 -+#define EARCRX_CMDC_XACT_RD51 0x1a2c -+#define EARCRX_CMDC_XACT_RD52 0x1a30 -+#define EARCRX_CMDC_XACT_RD53 0x1a34 -+#define EARCRX_CMDC_XACT_RD54 0x1a38 -+#define EARCRX_CMDC_XACT_RD55 0x1a3c -+#define EARCRX_CMDC_XACT_RD56 0x1a40 -+#define EARCRX_CMDC_XACT_RD57 0x1a44 -+#define EARCRX_CMDC_XACT_RD58 0x1a48 -+#define EARCRX_CMDC_XACT_RD59 0x1a4c -+#define EARCRX_CMDC_XACT_RD60 0x1a50 -+#define EARCRX_CMDC_XACT_RD61 0x1a54 -+#define EARCRX_CMDC_XACT_RD62 0x1a58 -+#define EARCRX_CMDC_XACT_RD63 0x1a5c -+#define EARCRX_CMDC_XACT_RD64 0x1a60 -+#define EARCRX_CMDC_SYNC_CONFIG 0x1b00 -+/* eARC RX DMAC Registers */ -+#define EARCRX_DMAC_PHY_CONTROL 0x1c00 -+#define EARCRX_DMAC_CONFIG 0x1c08 -+#define EARCRX_DMAC_CONTROL0 0x1c0c -+#define EARCRX_DMAC_AUDIO_EN BIT(1) -+#define EARCRX_DMAC_EN BIT(0) -+#define EARCRX_DMAC_CONTROL1 0x1c10 -+#define EARCRX_DMAC_STATUS 0x1c14 -+#define EARCRX_DMAC_CHSTATUS0 0x1c18 -+#define EARCRX_DMAC_CHSTATUS1 0x1c1c -+#define EARCRX_DMAC_CHSTATUS2 0x1c20 -+#define EARCRX_DMAC_CHSTATUS3 0x1c24 -+#define EARCRX_DMAC_CHSTATUS4 0x1c28 -+#define EARCRX_DMAC_CHSTATUS5 0x1c2c -+#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC0 0x1c30 -+#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC1 0x1c34 -+#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC2 0x1c38 -+#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC3 0x1c3c -+#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC4 0x1c40 -+#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC5 0x1c44 -+#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC6 0x1c48 -+#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC7 0x1c4c -+#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC8 0x1c50 -+#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC9 0x1c54 -+#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC10 0x1c58 -+#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC11 0x1c5c -+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT0 0x1c60 -+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT1 0x1c64 -+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT2 0x1c68 -+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT3 0x1c6c -+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT4 0x1c70 -+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT5 0x1c74 -+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT6 0x1c78 -+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT7 0x1c7c -+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT8 0x1c80 -+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT9 0x1c84 -+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT10 0x1c88 -+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT11 0x1c8c -+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT0 0x1c90 -+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT1 0x1c94 -+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT2 0x1c98 -+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT3 0x1c9c -+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT4 0x1ca0 -+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT5 0x1ca4 -+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT6 0x1ca8 -+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT7 0x1cac -+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT8 0x1cb0 -+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT9 0x1cb4 -+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT10 0x1cb8 -+#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT11 0x1cbc -+#define EARCRX_DMAC_USRDATA_MSG_GENERIC0 0x1cc0 -+#define EARCRX_DMAC_USRDATA_MSG_GENERIC1 0x1cc4 -+#define EARCRX_DMAC_USRDATA_MSG_GENERIC2 0x1cc8 -+#define EARCRX_DMAC_USRDATA_MSG_GENERIC3 0x1ccc -+#define EARCRX_DMAC_USRDATA_MSG_GENERIC4 0x1cd0 -+#define EARCRX_DMAC_USRDATA_MSG_GENERIC5 0x1cd4 -+#define EARCRX_DMAC_USRDATA_MSG_GENERIC6 0x1cd8 -+#define EARCRX_DMAC_USRDATA_MSG_GENERIC7 0x1cdc -+#define EARCRX_DMAC_USRDATA_MSG_GENERIC8 0x1ce0 -+#define EARCRX_DMAC_USRDATA_MSG_GENERIC9 0x1ce4 -+#define EARCRX_DMAC_USRDATA_MSG_GENERIC10 0x1ce8 -+#define EARCRX_DMAC_USRDATA_MSG_GENERIC11 0x1cec -+#define EARCRX_DMAC_USRDATA_MSG_GENERIC12 0x1cf0 -+#define EARCRX_DMAC_USRDATA_MSG_GENERIC13 0x1cf4 -+#define EARCRX_DMAC_USRDATA_MSG_GENERIC14 0x1cf8 -+#define EARCRX_DMAC_USRDATA_MSG_GENERIC15 0x1cfc -+#define EARCRX_DMAC_USRDATA_MSG_GENERIC16 0x1d00 -+#define EARCRX_DMAC_USRDATA_MSG_GENERIC17 0x1d04 -+#define EARCRX_DMAC_USRDATA_MSG_GENERIC18 0x1d08 -+#define EARCRX_DMAC_USRDATA_MSG_GENERIC19 0x1d0c -+#define EARCRX_DMAC_USRDATA_MSG_GENERIC20 0x1d10 -+#define EARCRX_DMAC_USRDATA_MSG_GENERIC21 0x1d14 -+#define EARCRX_DMAC_USRDATA_MSG_GENERIC22 0x1d18 -+#define EARCRX_DMAC_USRDATA_MSG_GENERIC23 0x1d1c -+#define EARCRX_DMAC_USRDATA_MSG_GENERIC24 0x1d20 -+#define EARCRX_DMAC_USRDATA_MSG_GENERIC25 0x1d24 -+#define EARCRX_DMAC_USRDATA_MSG_GENERIC26 0x1d28 -+#define EARCRX_DMAC_USRDATA_MSG_GENERIC27 0x1d2c -+#define EARCRX_DMAC_USRDATA_MSG_GENERIC28 0x1d30 -+#define EARCRX_DMAC_USRDATA_MSG_GENERIC29 0x1d34 -+#define EARCRX_DMAC_USRDATA_MSG_GENERIC30 0x1d38 -+#define EARCRX_DMAC_USRDATA_MSG_GENERIC31 0x1d3c -+#define EARCRX_DMAC_USRDATA_MSG_GENERIC32 0x1d40 -+#define EARCRX_DMAC_CHSTATUS_STREAMER0 0x1d44 -+#define EARCRX_DMAC_CHSTATUS_STREAMER1 0x1d48 -+#define EARCRX_DMAC_CHSTATUS_STREAMER2 0x1d4c -+#define EARCRX_DMAC_CHSTATUS_STREAMER3 0x1d50 -+#define EARCRX_DMAC_CHSTATUS_STREAMER4 0x1d54 -+#define EARCRX_DMAC_CHSTATUS_STREAMER5 0x1d58 -+#define EARCRX_DMAC_CHSTATUS_STREAMER6 0x1d5c -+#define EARCRX_DMAC_CHSTATUS_STREAMER7 0x1d60 -+#define EARCRX_DMAC_CHSTATUS_STREAMER8 0x1d64 -+#define EARCRX_DMAC_CHSTATUS_STREAMER9 0x1d68 -+#define EARCRX_DMAC_CHSTATUS_STREAMER10 0x1d6c -+#define EARCRX_DMAC_CHSTATUS_STREAMER11 0x1d70 -+#define EARCRX_DMAC_CHSTATUS_STREAMER12 0x1d74 -+#define EARCRX_DMAC_CHSTATUS_STREAMER13 0x1d78 -+#define EARCRX_DMAC_CHSTATUS_STREAMER14 0x1d7c -+#define EARCRX_DMAC_USRDATA_STREAMER0 0x1d80 -+/* Main Unit Interrupt Registers */ -+#define MAIN_INTVEC_INDEX 0x3000 -+#define MAINUNIT_0_INT_STATUS 0x3010 -+#define MAINUNIT_0_INT_MASK_N 0x3014 -+#define MAINUNIT_0_INT_CLEAR 0x3018 -+#define MAINUNIT_0_INT_FORCE 0x301c -+#define MAINUNIT_1_INT_STATUS 0x3020 -+#define FLT_EXIT_TO_LTSL_IRQ BIT(22) -+#define FLT_EXIT_TO_LTS4_IRQ BIT(21) -+#define FLT_EXIT_TO_LTSP_IRQ BIT(20) -+#define SCDC_NACK_RCVD_IRQ BIT(12) -+#define SCDC_RR_REPLY_STOP_IRQ BIT(11) -+#define SCDC_UPD_FLAGS_CLR_IRQ BIT(10) -+#define SCDC_UPD_FLAGS_CHG_IRQ BIT(9) -+#define SCDC_UPD_FLAGS_RD_IRQ BIT(8) -+#define I2CM_NACK_RCVD_IRQ BIT(2) -+#define I2CM_READ_REQUEST_IRQ BIT(1) -+#define I2CM_OP_DONE_IRQ BIT(0) -+#define MAINUNIT_1_INT_MASK_N 0x3024 -+#define I2CM_NACK_RCVD_MASK_N BIT(2) -+#define I2CM_READ_REQUEST_MASK_N BIT(1) -+#define I2CM_OP_DONE_MASK_N BIT(0) -+#define MAINUNIT_1_INT_CLEAR 0x3028 -+#define I2CM_NACK_RCVD_CLEAR BIT(2) -+#define I2CM_READ_REQUEST_CLEAR BIT(1) -+#define I2CM_OP_DONE_CLEAR BIT(0) -+#define MAINUNIT_1_INT_FORCE 0x302c -+/* AVPUNIT Interrupt Registers */ -+#define AVP_INTVEC_INDEX 0x3800 -+#define AVP_0_INT_STATUS 0x3810 -+#define AVP_0_INT_MASK_N 0x3814 -+#define AVP_0_INT_CLEAR 0x3818 -+#define AVP_0_INT_FORCE 0x381c -+#define AVP_1_INT_STATUS 0x3820 -+#define AVP_1_INT_MASK_N 0x3824 -+#define HDCP14_AUTH_CHG_MASK_N BIT(6) -+#define AVP_1_INT_CLEAR 0x3828 -+#define AVP_1_INT_FORCE 0x382c -+#define AVP_2_INT_STATUS 0x3830 -+#define AVP_2_INT_MASK_N 0x3834 -+#define AVP_2_INT_CLEAR 0x3838 -+#define AVP_2_INT_FORCE 0x383c -+#define AVP_3_INT_STATUS 0x3840 -+#define AVP_3_INT_MASK_N 0x3844 -+#define AVP_3_INT_CLEAR 0x3848 -+#define AVP_3_INT_FORCE 0x384c -+#define AVP_4_INT_STATUS 0x3850 -+#define AVP_4_INT_MASK_N 0x3854 -+#define AVP_4_INT_CLEAR 0x3858 -+#define AVP_4_INT_FORCE 0x385c -+#define AVP_5_INT_STATUS 0x3860 -+#define AVP_5_INT_MASK_N 0x3864 -+#define AVP_5_INT_CLEAR 0x3868 -+#define AVP_5_INT_FORCE 0x386c -+#define AVP_6_INT_STATUS 0x3870 -+#define AVP_6_INT_MASK_N 0x3874 -+#define AVP_6_INT_CLEAR 0x3878 -+#define AVP_6_INT_FORCE 0x387c -+/* CEC Interrupt Registers */ -+#define CEC_INT_STATUS 0x4000 -+#define CEC_INT_MASK_N 0x4004 -+#define CEC_INT_CLEAR 0x4008 -+#define CEC_INT_FORCE 0x400c -+/* eARC RX Interrupt Registers */ -+#define EARCRX_INTVEC_INDEX 0x4800 -+#define EARCRX_0_INT_STATUS 0x4810 -+#define EARCRX_CMDC_DISCOVERY_TIMEOUT_IRQ BIT(9) -+#define EARCRX_CMDC_DISCOVERY_DONE_IRQ BIT(8) -+#define EARCRX_0_INT_MASK_N 0x4814 -+#define EARCRX_0_INT_CLEAR 0x4818 -+#define EARCRX_0_INT_FORCE 0x481c -+#define EARCRX_1_INT_STATUS 0x4820 -+#define EARCRX_1_INT_MASK_N 0x4824 -+#define EARCRX_1_INT_CLEAR 0x4828 -+#define EARCRX_1_INT_FORCE 0x482c -+ -+#endif /* __DW_HDMI_QP_H__ */ -diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h -index 6a46baa0737c..a9cc4604222a 100644 ---- a/include/drm/bridge/dw_hdmi.h -+++ b/include/drm/bridge/dw_hdmi.h -@@ -131,6 +131,7 @@ struct dw_hdmi_plat_data { - unsigned long input_bus_encoding; - bool use_drm_infoframe; - bool ycbcr_420_allowed; -+ bool is_hdmi_qp; - - /* - * Private data passed to all the .mode_valid() and .configure_phy() -@@ -162,6 +163,7 @@ struct dw_hdmi_plat_data { - unsigned long mpixelclock); - - unsigned int disable_cec : 1; -+ - }; - - struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev, -@@ -206,6 +208,12 @@ void dw_hdmi_phy_update_hpd(struct dw_hdmi *hdmi, void *data, - bool force, bool disabled, bool rxsense); - void dw_hdmi_phy_setup_hpd(struct dw_hdmi *hdmi, void *data); - -+void dw_hdmi_qp_unbind(struct dw_hdmi *hdmi); -+struct dw_hdmi *dw_hdmi_qp_bind(struct platform_device *pdev, -+ struct drm_encoder *encoder, -+ struct dw_hdmi_plat_data *plat_data); -+void dw_hdmi_qp_resume(struct device *dev, struct dw_hdmi *hdmi); -+ - bool dw_hdmi_bus_fmt_is_420(struct dw_hdmi *hdmi); - - #endif /* __IMX_HDMI_H__ */ -diff --git a/include/drm/bridge/dw_hdmi_qp.h b/include/drm/bridge/dw_hdmi_qp.h -new file mode 100644 -index 000000000000..0b9c7a88a765 ---- /dev/null -+++ b/include/drm/bridge/dw_hdmi_qp.h -@@ -0,0 +1,37 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+/* -+ * Copyright (c) 2021-2022 Rockchip Electronics Co., Ltd. -+ * Copyright (c) 2024 Collabora Ltd. -+ */ -+ -+#ifndef __DW_HDMI_QP__ -+#define __DW_HDMI_QP__ -+ -+struct device; -+struct drm_display_info; -+struct drm_encoder; -+struct dw_hdmi_qp; -+struct platform_device; -+ -+struct dw_hdmi_qp_phy_ops { -+ int (*init)(struct dw_hdmi_qp *hdmi, void *data, -+ const struct drm_display_info *display); -+ void (*disable)(struct dw_hdmi_qp *hdmi, void *data); -+ enum drm_connector_status (*read_hpd)(struct dw_hdmi_qp *hdmi, void *data); -+ void (*setup_hpd)(struct dw_hdmi_qp *hdmi, void *data); -+}; -+ -+struct dw_hdmi_qp_plat_data { -+ const struct dw_hdmi_qp_phy_ops *phy_ops; -+ void *phy_data; -+}; -+ -+void dw_hdmi_qp_set_high_tmds_clock_ratio(struct dw_hdmi_qp *hdmi, -+ const struct drm_display_info *display); -+ -+void dw_hdmi_qp_unbind(struct dw_hdmi_qp *hdmi); -+struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev, -+ struct drm_encoder *encoder, -+ const struct dw_hdmi_qp_plat_data *plat_data); -+void dw_hdmi_qp_resume(struct device *dev, struct dw_hdmi_qp *hdmi); -+#endif /* __DW_HDMI_QP__ */ --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0039-drm-rockchip-Add-basic-RK3588-HDMI-output-support.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0039-drm-rockchip-Add-basic-RK3588-HDMI-output-support.patch deleted file mode 100644 index 19092f39a9..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0039-drm-rockchip-Add-basic-RK3588-HDMI-output-support.patch +++ /dev/null @@ -1,548 +0,0 @@ -From 2423a878b29161dc11a6c1f02c406962be2ce6f1 Mon Sep 17 00:00:00 2001 -From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> -Date: Sat, 6 Jul 2024 03:22:35 +0300 -Subject: [PATCH 39/63] drm/rockchip: Add basic RK3588 HDMI output support - -The RK3588 SoC family integrates the newer Synopsys DesignWare HDMI 2.1 -Quad-Pixel (QP) TX controller IP and a HDMI/eDP TX Combo PHY based on a -Samsung IP block. - -Add just the basic support for now, i.e. RGB output up to 4K@60Hz, -without audio, CEC or any of the HDMI 2.1 specific features. - -Co-developed-by: Algea Cao <algea.cao@rock-chips.com> -Signed-off-by: Algea Cao <algea.cao@rock-chips.com> -Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> ---- - drivers/gpu/drm/rockchip/Kconfig | 8 + - drivers/gpu/drm/rockchip/Makefile | 1 + - .../gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 452 ++++++++++++++++++ - drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 2 + - drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 1 + - 5 files changed, 464 insertions(+) - create mode 100644 drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c - -diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig -index 23c49e91f1cc..5343f879fd45 100644 ---- a/drivers/gpu/drm/rockchip/Kconfig -+++ b/drivers/gpu/drm/rockchip/Kconfig -@@ -8,6 +8,7 @@ config DRM_ROCKCHIP - select VIDEOMODE_HELPERS - select DRM_ANALOGIX_DP if ROCKCHIP_ANALOGIX_DP - select DRM_DW_HDMI if ROCKCHIP_DW_HDMI -+ select DRM_DW_HDMI_QP if ROCKCHIP_DW_HDMI_QP - select DRM_DW_MIPI_DSI if ROCKCHIP_DW_MIPI_DSI - select GENERIC_PHY if ROCKCHIP_DW_MIPI_DSI - select GENERIC_PHY_MIPI_DPHY if ROCKCHIP_DW_MIPI_DSI -@@ -63,6 +64,13 @@ config ROCKCHIP_DW_HDMI - enable HDMI on RK3288 or RK3399 based SoC, you should select - this option. - -+config ROCKCHIP_DW_HDMI_QP -+ bool "Rockchip specific extensions for Synopsys DW HDMI QP" -+ help -+ This selects support for Rockchip SoC specific extensions -+ for the Synopsys DesignWare HDMI QP driver. If you want to -+ enable HDMI on RK3588 based SoC, you should select this option. -+ - config ROCKCHIP_DW_MIPI_DSI - bool "Rockchip specific extensions for Synopsys DW MIPI DSI" - select GENERIC_PHY_MIPI_DPHY -diff --git a/drivers/gpu/drm/rockchip/Makefile b/drivers/gpu/drm/rockchip/Makefile -index 3ff7b21c0414..3eab662a5a1d 100644 ---- a/drivers/gpu/drm/rockchip/Makefile -+++ b/drivers/gpu/drm/rockchip/Makefile -@@ -11,6 +11,7 @@ rockchipdrm-$(CONFIG_ROCKCHIP_VOP) += rockchip_drm_vop.o rockchip_vop_reg.o - rockchipdrm-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o - rockchipdrm-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o - rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o -+rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI_QP) += dw_hdmi_qp-rockchip.o - rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi-rockchip.o - rockchipdrm-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o - rockchipdrm-$(CONFIG_ROCKCHIP_LVDS) += rockchip_lvds.o -diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c -new file mode 100644 -index 000000000000..353c9e3d5051 ---- /dev/null -+++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c -@@ -0,0 +1,452 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ * Copyright (c) 2021-2022 Rockchip Electronics Co., Ltd. -+ * Copyright (c) 2024 Collabora Ltd. -+ * -+ * Author: Algea Cao <algea.cao@rock-chips.com> -+ * Author: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> -+ */ -+ -+#include <linux/clk.h> -+#include <linux/gpio/consumer.h> -+#include <linux/mfd/syscon.h> -+#include <linux/module.h> -+#include <linux/platform_device.h> -+#include <linux/phy/phy.h> -+#include <linux/regmap.h> -+ -+#include <drm/bridge/dw_hdmi_qp.h> -+#include <drm/drm_bridge_connector.h> -+#include <drm/drm_of.h> -+#include <drm/drm_probe_helper.h> -+#include <drm/drm_simple_kms_helper.h> -+ -+#include "rockchip_drm_drv.h" -+ -+#define RK3588_GRF_SOC_CON2 0x0308 -+#define RK3588_HDMI0_HPD_INT_MSK BIT(13) -+#define RK3588_HDMI0_HPD_INT_CLR BIT(12) -+#define RK3588_GRF_SOC_CON7 0x031c -+#define RK3588_SET_HPD_PATH_MASK GENMASK(13, 12) -+#define RK3588_GRF_SOC_STATUS1 0x0384 -+#define RK3588_HDMI0_LEVEL_INT BIT(16) -+#define RK3588_GRF_VO1_CON3 0x000c -+#define RK3588_SCLIN_MASK BIT(9) -+#define RK3588_SDAIN_MASK BIT(10) -+#define RK3588_MODE_MASK BIT(11) -+#define RK3588_I2S_SEL_MASK BIT(13) -+#define RK3588_GRF_VO1_CON9 0x0024 -+#define RK3588_HDMI0_GRANT_SEL BIT(10) -+ -+#define HIWORD_UPDATE(val, mask) (val | (mask) << 16) -+ -+struct rockchip_hdmi_qp { -+ struct device *dev; -+ struct regmap *regmap; -+ struct regmap *vo1_regmap; -+ struct rockchip_encoder encoder; -+ struct clk *ref_clk; -+ struct dw_hdmi_qp *hdmi; -+ struct phy *phy; -+ struct gpio_desc *enable_gpio; -+ struct delayed_work hpd_work; -+}; -+ -+static struct rockchip_hdmi_qp *to_rockchip_hdmi_qp(struct drm_encoder *encoder) -+{ -+ struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder); -+ -+ return container_of(rkencoder, struct rockchip_hdmi_qp, encoder); -+} -+ -+static int dw_hdmi_qp_rockchip_parse_dt(struct rockchip_hdmi_qp *hdmi) -+{ -+ static const char * const opt_clk_names[] = { -+ "pclk", "hdp", "earc", "aud", "hclk_vo1", -+ }; -+ struct device_node *np = hdmi->dev->of_node; -+ struct clk *opt_clk; -+ int ret, i; -+ -+ hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); -+ if (IS_ERR(hdmi->regmap)) { -+ drm_err(hdmi, "Unable to get rockchip,grf\n"); -+ return PTR_ERR(hdmi->regmap); -+ } -+ -+ hdmi->vo1_regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,vo1_grf"); -+ if (IS_ERR(hdmi->vo1_regmap)) { -+ drm_err(hdmi, "Unable to get rockchip,vo1_grf\n"); -+ return PTR_ERR(hdmi->vo1_regmap); -+ } -+ -+ hdmi->ref_clk = devm_clk_get_enabled(hdmi->dev, "ref"); -+ if (IS_ERR(hdmi->ref_clk)) { -+ ret = PTR_ERR(hdmi->ref_clk); -+ if (ret != -EPROBE_DEFER) -+ drm_err(hdmi, "failed to get reference clock: %d\n", ret); -+ return ret; -+ } -+ -+ for (i = 0; i < ARRAY_SIZE(opt_clk_names); i++) { -+ opt_clk = devm_clk_get_optional_enabled(hdmi->dev, opt_clk_names[i]); -+ -+ if (IS_ERR(opt_clk)) { -+ ret = PTR_ERR(opt_clk); -+ if (ret != -EPROBE_DEFER) -+ drm_err(hdmi, "failed to get %s clock: %d\n", -+ opt_clk_names[i], ret); -+ return ret; -+ } -+ } -+ -+ hdmi->enable_gpio = devm_gpiod_get_optional(hdmi->dev, "enable", -+ GPIOD_OUT_HIGH); -+ if (IS_ERR(hdmi->enable_gpio)) { -+ ret = PTR_ERR(hdmi->enable_gpio); -+ drm_err(hdmi, "failed to request enable GPIO: %d\n", ret); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static void -+dw_hdmi_qp_rockchip_encoder_mode_set(struct drm_encoder *encoder, -+ struct drm_display_mode *mode, -+ struct drm_display_mode *adj_mode) -+{ -+ struct rockchip_hdmi_qp *hdmi = to_rockchip_hdmi_qp(encoder); -+ -+ clk_set_rate(hdmi->ref_clk, adj_mode->clock * 1000); -+} -+ -+static void dw_hdmi_qp_rockchip_encoder_enable(struct drm_encoder *encoder) -+{ -+ struct rockchip_hdmi_qp *hdmi = to_rockchip_hdmi_qp(encoder); -+ struct drm_crtc *crtc = encoder->crtc; -+ int rate; -+ -+ /* Unconditionally switch to TMDS as FRL is not yet supported */ -+ gpiod_set_value(hdmi->enable_gpio, 1); -+ -+ if (crtc && crtc->state) { -+ clk_set_rate(hdmi->ref_clk, -+ crtc->state->adjusted_mode.crtc_clock * 1000); -+ /* -+ * FIXME: Temporary workaround to pass pixel clock rate -+ * to the PHY driver until phy_configure_opts_hdmi -+ * becomes available in the PHY API. See also the related -+ * comment in rk_hdptx_phy_power_on() from -+ * drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c -+ */ -+ if (hdmi->phy) { -+ rate = crtc->state->mode.clock * 10; -+ phy_set_bus_width(hdmi->phy, rate); -+ drm_dbg(hdmi, "%s set bus_width=%u\n", __func__, rate); -+ } -+ } -+} -+ -+static int -+dw_hdmi_qp_rockchip_encoder_atomic_check(struct drm_encoder *encoder, -+ struct drm_crtc_state *crtc_state, -+ struct drm_connector_state *conn_state) -+{ -+ struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state); -+ -+ s->output_mode = ROCKCHIP_OUT_MODE_AAAA; -+ s->output_type = DRM_MODE_CONNECTOR_HDMIA; -+ -+ return 0; -+} -+ -+static const struct -+drm_encoder_helper_funcs dw_hdmi_qp_rockchip_encoder_helper_funcs = { -+ .mode_set = dw_hdmi_qp_rockchip_encoder_mode_set, -+ .enable = dw_hdmi_qp_rockchip_encoder_enable, -+ .atomic_check = dw_hdmi_qp_rockchip_encoder_atomic_check, -+}; -+ -+static int dw_hdmi_qp_rk3588_phy_init(struct dw_hdmi_qp *dw_hdmi, void *data, -+ const struct drm_display_info *display) -+{ -+ struct rockchip_hdmi_qp *hdmi = (struct rockchip_hdmi_qp *)data; -+ -+ dw_hdmi_qp_set_high_tmds_clock_ratio(dw_hdmi, display); -+ -+ return phy_power_on(hdmi->phy); -+} -+ -+static void dw_hdmi_qp_rk3588_phy_disable(struct dw_hdmi_qp *dw_hdmi, -+ void *data) -+{ -+ struct rockchip_hdmi_qp *hdmi = (struct rockchip_hdmi_qp *)data; -+ -+ phy_power_off(hdmi->phy); -+} -+ -+static enum drm_connector_status -+dw_hdmi_qp_rk3588_read_hpd(struct dw_hdmi_qp *dw_hdmi, void *data) -+{ -+ struct rockchip_hdmi_qp *hdmi = (struct rockchip_hdmi_qp *)data; -+ u32 val; -+ -+ regmap_read(hdmi->regmap, RK3588_GRF_SOC_STATUS1, &val); -+ -+ return val & RK3588_HDMI0_LEVEL_INT ? -+ connector_status_connected : connector_status_disconnected; -+} -+ -+static void dw_hdmi_qp_rk3588_setup_hpd(struct dw_hdmi_qp *dw_hdmi, void *data) -+{ -+ struct rockchip_hdmi_qp *hdmi = (struct rockchip_hdmi_qp *)data; -+ -+ regmap_write(hdmi->regmap, -+ RK3588_GRF_SOC_CON2, -+ HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_CLR, -+ RK3588_HDMI0_HPD_INT_CLR | -+ RK3588_HDMI0_HPD_INT_MSK)); -+} -+ -+static const struct dw_hdmi_qp_phy_ops rk3588_hdmi_phy_ops = { -+ .init = dw_hdmi_qp_rk3588_phy_init, -+ .disable = dw_hdmi_qp_rk3588_phy_disable, -+ .read_hpd = dw_hdmi_qp_rk3588_read_hpd, -+ .setup_hpd = dw_hdmi_qp_rk3588_setup_hpd, -+}; -+ -+static void dw_hdmi_qp_rk3588_hpd_work(struct work_struct *work) -+{ -+ struct rockchip_hdmi_qp *hdmi = container_of(work, -+ struct rockchip_hdmi_qp, -+ hpd_work.work); -+ struct drm_device *drm = hdmi->encoder.encoder.dev; -+ bool changed; -+ -+ if (drm) { -+ changed = drm_helper_hpd_irq_event(drm); -+ if (changed) -+ drm_dbg(hdmi, "connector status changed\n"); -+ } -+} -+ -+static irqreturn_t dw_hdmi_qp_rk3588_hardirq(int irq, void *dev_id) -+{ -+ struct rockchip_hdmi_qp *hdmi = dev_id; -+ u32 intr_stat, val; -+ -+ regmap_read(hdmi->regmap, RK3588_GRF_SOC_STATUS1, &intr_stat); -+ -+ if (intr_stat) { -+ val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_MSK, -+ RK3588_HDMI0_HPD_INT_MSK); -+ regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val); -+ return IRQ_WAKE_THREAD; -+ } -+ -+ return IRQ_NONE; -+} -+ -+static irqreturn_t dw_hdmi_qp_rk3588_irq(int irq, void *dev_id) -+{ -+ struct rockchip_hdmi_qp *hdmi = dev_id; -+ u32 intr_stat, val; -+ int debounce_ms; -+ -+ regmap_read(hdmi->regmap, RK3588_GRF_SOC_STATUS1, &intr_stat); -+ if (!intr_stat) -+ return IRQ_NONE; -+ -+ val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_CLR, -+ RK3588_HDMI0_HPD_INT_CLR); -+ regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val); -+ -+ debounce_ms = intr_stat & RK3588_HDMI0_LEVEL_INT ? 150 : 20; -+ mod_delayed_work(system_wq, &hdmi->hpd_work, -+ msecs_to_jiffies(debounce_ms)); -+ -+ val |= HIWORD_UPDATE(0, RK3588_HDMI0_HPD_INT_MSK); -+ regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val); -+ -+ return IRQ_HANDLED; -+} -+ -+static const struct of_device_id dw_hdmi_qp_rockchip_dt_ids[] = { -+ { .compatible = "rockchip,rk3588-dw-hdmi-qp", -+ .data = &rk3588_hdmi_phy_ops }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, dw_hdmi_qp_rockchip_dt_ids); -+ -+static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master, -+ void *data) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ struct drm_device *drm = data; -+ struct dw_hdmi_qp_plat_data plat_data; -+ struct drm_connector *connector; -+ struct drm_encoder *encoder; -+ struct rockchip_hdmi_qp *hdmi; -+ int ret, irq; -+ u32 val; -+ -+ if (!pdev->dev.of_node) -+ return -ENODEV; -+ -+ hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL); -+ if (!hdmi) -+ return -ENOMEM; -+ -+ plat_data.phy_ops = of_device_get_match_data(dev); -+ if (!plat_data.phy_ops) -+ return -ENODEV; -+ -+ plat_data.phy_data = hdmi; -+ hdmi->dev = &pdev->dev; -+ -+ encoder = &hdmi->encoder.encoder; -+ encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); -+ -+ rockchip_drm_encoder_set_crtc_endpoint_id(&hdmi->encoder, -+ dev->of_node, 0, 0); -+ /* -+ * If we failed to find the CRTC(s) which this encoder is -+ * supposed to be connected to, it's because the CRTC has -+ * not been registered yet. Defer probing, and hope that -+ * the required CRTC is added later. -+ */ -+ if (encoder->possible_crtcs == 0) -+ return -EPROBE_DEFER; -+ -+ ret = dw_hdmi_qp_rockchip_parse_dt(hdmi); -+ if (ret) -+ return ret; -+ -+ hdmi->phy = devm_phy_optional_get(dev, "hdmi"); -+ if (IS_ERR(hdmi->phy)) { -+ ret = PTR_ERR(hdmi->phy); -+ if (ret != -EPROBE_DEFER) -+ drm_err(hdmi, "failed to get phy: %d\n", ret); -+ return ret; -+ } -+ -+ val = HIWORD_UPDATE(RK3588_SCLIN_MASK, RK3588_SCLIN_MASK) | -+ HIWORD_UPDATE(RK3588_SDAIN_MASK, RK3588_SDAIN_MASK) | -+ HIWORD_UPDATE(RK3588_MODE_MASK, RK3588_MODE_MASK) | -+ HIWORD_UPDATE(RK3588_I2S_SEL_MASK, RK3588_I2S_SEL_MASK); -+ regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON3, val); -+ -+ val = HIWORD_UPDATE(RK3588_SET_HPD_PATH_MASK, -+ RK3588_SET_HPD_PATH_MASK); -+ regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON7, val); -+ -+ val = HIWORD_UPDATE(RK3588_HDMI0_GRANT_SEL, -+ RK3588_HDMI0_GRANT_SEL); -+ regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON9, val); -+ -+ val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_MSK, RK3588_HDMI0_HPD_INT_MSK); -+ regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val); -+ -+ INIT_DELAYED_WORK(&hdmi->hpd_work, dw_hdmi_qp_rk3588_hpd_work); -+ -+ irq = platform_get_irq(pdev, 4); -+ if (irq < 0) -+ return irq; -+ -+ ret = devm_request_threaded_irq(hdmi->dev, irq, -+ dw_hdmi_qp_rk3588_hardirq, -+ dw_hdmi_qp_rk3588_irq, -+ IRQF_SHARED, "dw-hdmi-qp-hpd", -+ hdmi); -+ if (ret) -+ return ret; -+ -+ drm_encoder_helper_add(encoder, &dw_hdmi_qp_rockchip_encoder_helper_funcs); -+ drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS); -+ -+ platform_set_drvdata(pdev, hdmi); -+ -+ hdmi->hdmi = dw_hdmi_qp_bind(pdev, encoder, &plat_data); -+ if (IS_ERR(hdmi->hdmi)) { -+ ret = PTR_ERR(hdmi->hdmi); -+ drm_encoder_cleanup(encoder); -+ return ret; -+ } -+ -+ connector = drm_bridge_connector_init(drm, encoder); -+ if (IS_ERR(connector)) { -+ ret = PTR_ERR(connector); -+ drm_err(hdmi, "failed to init bridge connector: %d\n", ret); -+ return ret; -+ } -+ -+ return drm_connector_attach_encoder(connector, encoder); -+} -+ -+static void dw_hdmi_qp_rockchip_unbind(struct device *dev, struct device *master, -+ void *data) -+{ -+ struct rockchip_hdmi_qp *hdmi = dev_get_drvdata(dev); -+ -+ cancel_delayed_work_sync(&hdmi->hpd_work); -+ dw_hdmi_qp_unbind(hdmi->hdmi); -+ -+ drm_encoder_cleanup(&hdmi->encoder.encoder); -+} -+ -+static const struct component_ops dw_hdmi_qp_rockchip_ops = { -+ .bind = dw_hdmi_qp_rockchip_bind, -+ .unbind = dw_hdmi_qp_rockchip_unbind, -+}; -+ -+static int dw_hdmi_qp_rockchip_probe(struct platform_device *pdev) -+{ -+ return component_add(&pdev->dev, &dw_hdmi_qp_rockchip_ops); -+} -+ -+static void dw_hdmi_qp_rockchip_remove(struct platform_device *pdev) -+{ -+ component_del(&pdev->dev, &dw_hdmi_qp_rockchip_ops); -+} -+ -+static int __maybe_unused dw_hdmi_qp_rockchip_resume(struct device *dev) -+{ -+ struct rockchip_hdmi_qp *hdmi = dev_get_drvdata(dev); -+ u32 val; -+ -+ val = HIWORD_UPDATE(RK3588_SCLIN_MASK, RK3588_SCLIN_MASK) | -+ HIWORD_UPDATE(RK3588_SDAIN_MASK, RK3588_SDAIN_MASK) | -+ HIWORD_UPDATE(RK3588_MODE_MASK, RK3588_MODE_MASK) | -+ HIWORD_UPDATE(RK3588_I2S_SEL_MASK, RK3588_I2S_SEL_MASK); -+ regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON3, val); -+ -+ val = HIWORD_UPDATE(RK3588_SET_HPD_PATH_MASK, -+ RK3588_SET_HPD_PATH_MASK); -+ regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON7, val); -+ -+ val = HIWORD_UPDATE(RK3588_HDMI0_GRANT_SEL, -+ RK3588_HDMI0_GRANT_SEL); -+ regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON9, val); -+ -+ dw_hdmi_qp_resume(dev, hdmi->hdmi); -+ -+ if (hdmi->encoder.encoder.dev) -+ drm_helper_hpd_irq_event(hdmi->encoder.encoder.dev); -+ -+ return 0; -+} -+ -+static const struct dev_pm_ops dw_hdmi_qp_rockchip_pm = { -+ SET_SYSTEM_SLEEP_PM_OPS(NULL, dw_hdmi_qp_rockchip_resume) -+}; -+ -+struct platform_driver dw_hdmi_qp_rockchip_pltfm_driver = { -+ .probe = dw_hdmi_qp_rockchip_probe, -+ .remove_new = dw_hdmi_qp_rockchip_remove, -+ .driver = { -+ .name = "dwhdmiqp-rockchip", -+ .pm = &dw_hdmi_qp_rockchip_pm, -+ .of_match_table = dw_hdmi_qp_rockchip_dt_ids, -+ }, -+}; -diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c -index 11e5d10de4d7..ddf0be331c0a 100644 ---- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c -+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c -@@ -507,6 +507,8 @@ static int __init rockchip_drm_init(void) - ADD_ROCKCHIP_SUB_DRIVER(cdn_dp_driver, CONFIG_ROCKCHIP_CDN_DP); - ADD_ROCKCHIP_SUB_DRIVER(dw_hdmi_rockchip_pltfm_driver, - CONFIG_ROCKCHIP_DW_HDMI); -+ ADD_ROCKCHIP_SUB_DRIVER(dw_hdmi_qp_rockchip_pltfm_driver, -+ CONFIG_ROCKCHIP_DW_HDMI_QP); - ADD_ROCKCHIP_SUB_DRIVER(dw_mipi_dsi_rockchip_driver, - CONFIG_ROCKCHIP_DW_MIPI_DSI); - ADD_ROCKCHIP_SUB_DRIVER(inno_hdmi_driver, CONFIG_ROCKCHIP_INNO_HDMI); -diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h -index 8d566fcd80a2..24b4ce5ceaf1 100644 ---- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h -+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h -@@ -88,6 +88,7 @@ int rockchip_drm_encoder_set_crtc_endpoint_id(struct rockchip_encoder *rencoder, - int rockchip_drm_endpoint_is_subdriver(struct device_node *ep); - extern struct platform_driver cdn_dp_driver; - extern struct platform_driver dw_hdmi_rockchip_pltfm_driver; -+extern struct platform_driver dw_hdmi_qp_rockchip_pltfm_driver; - extern struct platform_driver dw_mipi_dsi_rockchip_driver; - extern struct platform_driver inno_hdmi_driver; - extern struct platform_driver rockchip_dp_driver; --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0040-arm64-defconfig-Enable-Rockchip-extensions-for-Synop.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0040-arm64-defconfig-Enable-Rockchip-extensions-for-Synop.patch deleted file mode 100644 index 585e0be4c0..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0040-arm64-defconfig-Enable-Rockchip-extensions-for-Synop.patch +++ /dev/null @@ -1,31 +0,0 @@ -From cd8b5fddf15090894f0a96443b03846b47cec08a Mon Sep 17 00:00:00 2001 -From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> -Date: Thu, 11 Jul 2024 14:48:43 +0300 -Subject: [PATCH 40/63] arm64: defconfig: Enable Rockchip extensions for - Synopsys DW HDMI QP - -Enable Rockchip specific extensions for the Synopsys DesignWare HDMI QP -driver. - -This is needed for the HDMI output support on RK3588 SoC based boards. - -Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> ---- - arch/arm64/configs/defconfig | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig -index 5a2912bd9ce5..0c9dd4af485c 100644 ---- a/arch/arm64/configs/defconfig -+++ b/arch/arm64/configs/defconfig -@@ -872,6 +872,7 @@ CONFIG_ROCKCHIP_VOP2=y - CONFIG_ROCKCHIP_ANALOGIX_DP=y - CONFIG_ROCKCHIP_CDN_DP=y - CONFIG_ROCKCHIP_DW_HDMI=y -+CONFIG_ROCKCHIP_DW_HDMI_QP=y - CONFIG_ROCKCHIP_DW_MIPI_DSI=y - CONFIG_ROCKCHIP_INNO_HDMI=y - CONFIG_ROCKCHIP_LVDS=y --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0041-MAINTAINERS-Add-entry-for-Synopsys-DesignWare-HDMI-R.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0041-MAINTAINERS-Add-entry-for-Synopsys-DesignWare-HDMI-R.patch deleted file mode 100644 index d344f1440b..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0041-MAINTAINERS-Add-entry-for-Synopsys-DesignWare-HDMI-R.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 26d8b36f4558c2d04fe8b44558f987183a121dae Mon Sep 17 00:00:00 2001 -From: Shreeya Patel <shreeya.patel@collabora.com> -Date: Fri, 19 Jul 2024 18:10:29 +0530 -Subject: [PATCH 41/63] MAINTAINERS: Add entry for Synopsys DesignWare HDMI RX - Driver - -Add an entry for Synopsys DesignWare HDMI Receiver Controller -Driver. - -Signed-off-by: Shreeya Patel <shreeya.patel@collabora.com> -Reviewed-by: Christopher Obbard <chris.obbard@collabora.com> -Link: https://lore.kernel.org/r/20240719124032.26852-2-shreeya.patel@collabora.com -Signed-off-by: Sebastian Reichel <sre@kernel.org> ---- - MAINTAINERS | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/MAINTAINERS b/MAINTAINERS -index b878ddc99f94..7d26f859c9af 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -22429,6 +22429,14 @@ F: drivers/net/pcs/pcs-xpcs.c - F: drivers/net/pcs/pcs-xpcs.h - F: include/linux/pcs/pcs-xpcs.h - -+SYNOPSYS DESIGNWARE HDMI RX CONTROLLER DRIVER -+M: Shreeya Patel <shreeya.patel@collabora.com -+L: linux-media@vger.kernel.org -+L: kernel@collabora.com -+S: Maintained -+F: Documentation/devicetree/bindings/media/snps,dw-hdmi-rx.yaml -+F: drivers/media/platform/synopsys/hdmirx/* -+ - SYNOPSYS DESIGNWARE I2C DRIVER - M: Jarkko Nikula <jarkko.nikula@linux.intel.com> - R: Andy Shevchenko <andriy.shevchenko@linux.intel.com> --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0042-dt-bindings-media-Document-bindings-for-HDMI-RX-Cont.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0042-dt-bindings-media-Document-bindings-for-HDMI-RX-Cont.patch deleted file mode 100644 index 21c3ef5a95..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0042-dt-bindings-media-Document-bindings-for-HDMI-RX-Cont.patch +++ /dev/null @@ -1,161 +0,0 @@ -From 6e62a69ef97f08827810be29084904401df99462 Mon Sep 17 00:00:00 2001 -From: Shreeya Patel <shreeya.patel@collabora.com> -Date: Fri, 19 Jul 2024 18:10:30 +0530 -Subject: [PATCH 42/63] dt-bindings: media: Document bindings for HDMI RX - Controller - -Document bindings for the Synopsys DesignWare HDMI RX Controller. - -Reviewed-by: Rob Herring <robh@kernel.org> -Reviewed-by: Dmitry Osipenko <dmitry.osipenko@collabora.com> -Signed-off-by: Shreeya Patel <shreeya.patel@collabora.com> -Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com> -Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> -Link: https://lore.kernel.org/r/20240719124032.26852-3-shreeya.patel@collabora.com -Signed-off-by: Sebastian Reichel <sre@kernel.org> ---- - .../bindings/media/snps,dw-hdmi-rx.yaml | 132 ++++++++++++++++++ - 1 file changed, 132 insertions(+) - create mode 100644 Documentation/devicetree/bindings/media/snps,dw-hdmi-rx.yaml - -diff --git a/Documentation/devicetree/bindings/media/snps,dw-hdmi-rx.yaml b/Documentation/devicetree/bindings/media/snps,dw-hdmi-rx.yaml -new file mode 100644 -index 000000000000..510e94e9ca3a ---- /dev/null -+++ b/Documentation/devicetree/bindings/media/snps,dw-hdmi-rx.yaml -@@ -0,0 +1,132 @@ -+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) -+# Device Tree bindings for Synopsys DesignWare HDMI RX Controller -+ -+--- -+$id: http://devicetree.org/schemas/media/snps,dw-hdmi-rx.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: Synopsys DesignWare HDMI RX Controller -+ -+maintainers: -+ - Shreeya Patel <shreeya.patel@collabora.com> -+ -+description: -+ Synopsys DesignWare HDMI Input Controller preset on RK3588 SoCs -+ allowing devices to receive and decode high-resolution video streams -+ from external sources like media players, cameras, laptops, etc. -+ -+properties: -+ compatible: -+ items: -+ - const: rockchip,rk3588-hdmirx-ctrler -+ - const: snps,dw-hdmi-rx -+ -+ reg: -+ maxItems: 1 -+ -+ interrupts: -+ maxItems: 3 -+ -+ interrupt-names: -+ items: -+ - const: cec -+ - const: hdmi -+ - const: dma -+ -+ clocks: -+ maxItems: 7 -+ -+ clock-names: -+ items: -+ - const: aclk -+ - const: audio -+ - const: cr_para -+ - const: pclk -+ - const: ref -+ - const: hclk_s_hdmirx -+ - const: hclk_vo1 -+ -+ power-domains: -+ maxItems: 1 -+ -+ resets: -+ maxItems: 4 -+ -+ reset-names: -+ items: -+ - const: axi -+ - const: apb -+ - const: ref -+ - const: biu -+ -+ memory-region: -+ maxItems: 1 -+ -+ hpd-gpios: -+ description: GPIO specifier for HPD. -+ maxItems: 1 -+ -+ rockchip,grf: -+ $ref: /schemas/types.yaml#/definitions/phandle -+ description: -+ The phandle of the syscon node for the general register file -+ containing HDMIRX PHY status bits. -+ -+ rockchip,vo1-grf: -+ $ref: /schemas/types.yaml#/definitions/phandle -+ description: -+ The phandle of the syscon node for the Video Output GRF register -+ to enable EDID transfer through SDAIN and SCLIN. -+ -+required: -+ - compatible -+ - reg -+ - interrupts -+ - interrupt-names -+ - clocks -+ - clock-names -+ - power-domains -+ - resets -+ - pinctrl-0 -+ - hpd-gpios -+ -+additionalProperties: false -+ -+examples: -+ - | -+ #include <dt-bindings/clock/rockchip,rk3588-cru.h> -+ #include <dt-bindings/gpio/gpio.h> -+ #include <dt-bindings/interrupt-controller/arm-gic.h> -+ #include <dt-bindings/interrupt-controller/irq.h> -+ #include <dt-bindings/power/rk3588-power.h> -+ #include <dt-bindings/reset/rockchip,rk3588-cru.h> -+ hdmi_receiver: hdmi-receiver@fdee0000 { -+ compatible = "rockchip,rk3588-hdmirx-ctrler", "snps,dw-hdmi-rx"; -+ reg = <0xfdee0000 0x6000>; -+ interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH 0>, -+ <GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH 0>, -+ <GIC_SPI 179 IRQ_TYPE_LEVEL_HIGH 0>; -+ interrupt-names = "cec", "hdmi", "dma"; -+ clocks = <&cru ACLK_HDMIRX>, -+ <&cru CLK_HDMIRX_AUD>, -+ <&cru CLK_CR_PARA>, -+ <&cru PCLK_HDMIRX>, -+ <&cru CLK_HDMIRX_REF>, -+ <&cru PCLK_S_HDMIRX>, -+ <&cru HCLK_VO1>; -+ clock-names = "aclk", -+ "audio", -+ "cr_para", -+ "pclk", -+ "ref", -+ "hclk_s_hdmirx", -+ "hclk_vo1"; -+ power-domains = <&power RK3588_PD_VO1>; -+ resets = <&cru SRST_A_HDMIRX>, <&cru SRST_P_HDMIRX>, -+ <&cru SRST_HDMIRX_REF>, <&cru SRST_A_HDMIRX_BIU>; -+ reset-names = "axi", "apb", "ref", "biu"; -+ memory-region = <&hdmi_receiver_cma>; -+ pinctrl-0 = <&hdmim1_rx_cec &hdmim1_rx_hpdin &hdmim1_rx_scl &hdmim1_rx_sda &hdmirx_5v_detection>; -+ pinctrl-names = "default"; -+ hpd-gpios = <&gpio1 22 GPIO_ACTIVE_LOW>; -+ }; --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0043-arm64-dts-rockchip-Add-device-tree-support-for-HDMI-.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0043-arm64-dts-rockchip-Add-device-tree-support-for-HDMI-.patch deleted file mode 100644 index 03dc13ffe6..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0043-arm64-dts-rockchip-Add-device-tree-support-for-HDMI-.patch +++ /dev/null @@ -1,124 +0,0 @@ -From 557e82fc25c3d157c43eb3d4144047c9edc239b6 Mon Sep 17 00:00:00 2001 -From: Shreeya Patel <shreeya.patel@collabora.com> -Date: Fri, 19 Jul 2024 18:10:31 +0530 -Subject: [PATCH 43/63] arm64: dts: rockchip: Add device tree support for HDMI - RX Controller - -Add device tree support for Synopsys DesignWare HDMI RX -Controller. - -Reviewed-by: Dmitry Osipenko <dmitry.osipenko@collabora.com> -Tested-by: Dmitry Osipenko <dmitry.osipenko@collabora.com> -Co-developed-by: Dingxian Wen <shawn.wen@rock-chips.com> -Signed-off-by: Dingxian Wen <shawn.wen@rock-chips.com> -Signed-off-by: Shreeya Patel <shreeya.patel@collabora.com> -Link: https://lore.kernel.org/r/20240719124032.26852-4-shreeya.patel@collabora.com -Signed-off-by: Sebastian Reichel <sre@kernel.org> ---- - .../dts/rockchip/rk3588-base-pinctrl.dtsi | 14 +++++ - .../arm64/boot/dts/rockchip/rk3588-extra.dtsi | 57 +++++++++++++++++++ - 2 files changed, 71 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-base-pinctrl.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-base-pinctrl.dtsi -index d1368418502a..883d4c4ea8f0 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-base-pinctrl.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3588-base-pinctrl.dtsi -@@ -594,6 +594,20 @@ hdmim0_tx1_hpd: hdmim0-tx1-hpd { - /* hdmim0_tx1_hpd */ - <1 RK_PA6 5 &pcfg_pull_none>; - }; -+ -+ /omit-if-no-ref/ -+ hdmim1_rx: hdmim1-rx { -+ rockchip,pins = -+ /* hdmim1_rx_cec */ -+ <3 RK_PD1 5 &pcfg_pull_none>, -+ /* hdmim1_rx_scl */ -+ <3 RK_PD2 5 &pcfg_pull_none_smt>, -+ /* hdmim1_rx_sda */ -+ <3 RK_PD3 5 &pcfg_pull_none_smt>, -+ /* hdmim1_rx_hpdin */ -+ <3 RK_PD4 5 &pcfg_pull_none>; -+ }; -+ - /omit-if-no-ref/ - hdmim1_rx_cec: hdmim1-rx-cec { - rockchip,pins = -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi -index 0ce0934ec6b7..e441fa18fbf4 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi -@@ -7,6 +7,30 @@ - #include "rk3588-extra-pinctrl.dtsi" - - / { -+ reserved-memory { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ ranges; -+ -+ /* -+ * The 4k HDMI capture controller works only with 32bit -+ * phys addresses and doesn't support IOMMU. HDMI RX CMA -+ * must be reserved below 4GB. -+ * The size of 160MB was determined as follows: -+ * (3840 * 2160 pixels) * (4 bytes/pixel) * (2 frames/buffer) / 10^6 = 66MB -+ * To ensure sufficient support for practical use-cases, -+ * we doubled the 66MB value. -+ */ -+ hdmi_receiver_cma: hdmi-receiver-cma { -+ compatible = "shared-dma-pool"; -+ alloc-ranges = <0x0 0x0 0x0 0xffffffff>; -+ size = <0x0 (160 * 0x100000)>; /* 160MiB */ -+ alignment = <0x0 0x40000>; /* 64K */ -+ no-map; -+ status = "disabled"; -+ }; -+ }; -+ - usb_host1_xhci: usb@fc400000 { - compatible = "rockchip,rk3588-dwc3", "snps,dwc3"; - reg = <0x0 0xfc400000 0x0 0x400000>; -@@ -135,6 +159,39 @@ i2s10_8ch: i2s@fde00000 { - status = "disabled"; - }; - -+ hdmi_receiver: hdmi_receiver@fdee0000 { -+ compatible = "rockchip,rk3588-hdmirx-ctrler", "snps,dw-hdmi-rx"; -+ reg = <0x0 0xfdee0000 0x0 0x6000>; -+ power-domains = <&power RK3588_PD_VO1>; -+ rockchip,grf = <&sys_grf>; -+ rockchip,vo1-grf = <&vo1_grf>; -+ interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH 0>, -+ <GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH 0>, -+ <GIC_SPI 179 IRQ_TYPE_LEVEL_HIGH 0>; -+ interrupt-names = "cec", "hdmi", "dma"; -+ clocks = <&cru ACLK_HDMIRX>, -+ <&cru CLK_HDMIRX_AUD>, -+ <&cru CLK_CR_PARA>, -+ <&cru PCLK_HDMIRX>, -+ <&cru CLK_HDMIRX_REF>, -+ <&cru PCLK_S_HDMIRX>, -+ <&cru HCLK_VO1>; -+ clock-names = "aclk", -+ "audio", -+ "cr_para", -+ "pclk", -+ "ref", -+ "hclk_s_hdmirx", -+ "hclk_vo1"; -+ resets = <&cru SRST_A_HDMIRX>, <&cru SRST_P_HDMIRX>, -+ <&cru SRST_HDMIRX_REF>, <&cru SRST_A_HDMIRX_BIU>; -+ reset-names = "axi", "apb", "ref", "biu"; -+ memory-region = <&hdmi_receiver_cma>; -+ pinctrl-0 = <&hdmim1_rx>; -+ pinctrl-names = "default"; -+ status = "disabled"; -+ }; -+ - pcie3x4: pcie@fe150000 { - compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie"; - #address-cells = <3>; --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0044-media-platform-synopsys-Add-support-for-HDMI-input-d.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0044-media-platform-synopsys-Add-support-for-HDMI-input-d.patch deleted file mode 100644 index 3eebc2ae0c..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0044-media-platform-synopsys-Add-support-for-HDMI-input-d.patch +++ /dev/null @@ -1,3537 +0,0 @@ -From 5947fcef812cb82bf2075e23449e0761db60111a Mon Sep 17 00:00:00 2001 -From: Shreeya Patel <shreeya.patel@collabora.com> -Date: Tue, 1 Oct 2024 19:39:59 +0300 -Subject: [PATCH 44/63] media: platform: synopsys: Add support for HDMI input - driver - -Add initial support for the Synopsys DesignWare HDMI RX -Controller Driver used by Rockchip RK3588. The driver -supports: - - HDMI 1.4b and 2.0 modes (HDMI 4k@60Hz) - - RGB888, YUV422, YUV444 and YCC420 pixel formats - - CEC - - EDID configuration - -The hardware also has Audio and HDCP capabilities, but these are -not yet supported by the driver. - -Co-developed-by: Dingxian Wen <shawn.wen@rock-chips.com> -Signed-off-by: Dingxian Wen <shawn.wen@rock-chips.com> -Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com> -Signed-off-by: Shreeya Patel <shreeya.patel@collabora.com> ---- - drivers/media/platform/Kconfig | 1 + - drivers/media/platform/Makefile | 1 + - drivers/media/platform/synopsys/Kconfig | 3 + - drivers/media/platform/synopsys/Makefile | 2 + - .../media/platform/synopsys/hdmirx/Kconfig | 27 + - .../media/platform/synopsys/hdmirx/Makefile | 4 + - .../platform/synopsys/hdmirx/snps_hdmirx.c | 2663 +++++++++++++++++ - .../platform/synopsys/hdmirx/snps_hdmirx.h | 394 +++ - .../synopsys/hdmirx/snps_hdmirx_cec.c | 283 ++ - .../synopsys/hdmirx/snps_hdmirx_cec.h | 44 + - 10 files changed, 3422 insertions(+) - create mode 100644 drivers/media/platform/synopsys/Kconfig - create mode 100644 drivers/media/platform/synopsys/Makefile - create mode 100644 drivers/media/platform/synopsys/hdmirx/Kconfig - create mode 100644 drivers/media/platform/synopsys/hdmirx/Makefile - create mode 100644 drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c - create mode 100644 drivers/media/platform/synopsys/hdmirx/snps_hdmirx.h - create mode 100644 drivers/media/platform/synopsys/hdmirx/snps_hdmirx_cec.c - create mode 100644 drivers/media/platform/synopsys/hdmirx/snps_hdmirx_cec.h - -diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig -index 85d2627776b6..9287faafdce5 100644 ---- a/drivers/media/platform/Kconfig -+++ b/drivers/media/platform/Kconfig -@@ -85,6 +85,7 @@ source "drivers/media/platform/rockchip/Kconfig" - source "drivers/media/platform/samsung/Kconfig" - source "drivers/media/platform/st/Kconfig" - source "drivers/media/platform/sunxi/Kconfig" -+source "drivers/media/platform/synopsys/Kconfig" - source "drivers/media/platform/ti/Kconfig" - source "drivers/media/platform/verisilicon/Kconfig" - source "drivers/media/platform/via/Kconfig" -diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile -index ace4e34483dd..6fd7db0541c7 100644 ---- a/drivers/media/platform/Makefile -+++ b/drivers/media/platform/Makefile -@@ -28,6 +28,7 @@ obj-y += rockchip/ - obj-y += samsung/ - obj-y += st/ - obj-y += sunxi/ -+obj-y += synopsys/ - obj-y += ti/ - obj-y += verisilicon/ - obj-y += via/ -diff --git a/drivers/media/platform/synopsys/Kconfig b/drivers/media/platform/synopsys/Kconfig -new file mode 100644 -index 000000000000..4fd521f78425 ---- /dev/null -+++ b/drivers/media/platform/synopsys/Kconfig -@@ -0,0 +1,3 @@ -+# SPDX-License-Identifier: GPL-2.0-only -+ -+source "drivers/media/platform/synopsys/hdmirx/Kconfig" -diff --git a/drivers/media/platform/synopsys/Makefile b/drivers/media/platform/synopsys/Makefile -new file mode 100644 -index 000000000000..3b12c574dd67 ---- /dev/null -+++ b/drivers/media/platform/synopsys/Makefile -@@ -0,0 +1,2 @@ -+# SPDX-License-Identifier: GPL-2.0-only -+obj-y += hdmirx/ -diff --git a/drivers/media/platform/synopsys/hdmirx/Kconfig b/drivers/media/platform/synopsys/hdmirx/Kconfig -new file mode 100644 -index 000000000000..3f96f6c97cf0 ---- /dev/null -+++ b/drivers/media/platform/synopsys/hdmirx/Kconfig -@@ -0,0 +1,27 @@ -+# SPDX-License-Identifier: GPL-2.0 -+ -+config VIDEO_SYNOPSYS_HDMIRX -+ tristate "Synopsys DesignWare HDMI Receiver driver" -+ depends on VIDEO_DEV -+ select MEDIA_CONTROLLER -+ select VIDEO_V4L2_SUBDEV_API -+ select VIDEOBUF2_DMA_CONTIG -+ select CEC_CORE -+ select CEC_NOTIFIER -+ select HDMI -+ help -+ Support for Synopsys HDMI HDMI RX Controller. -+ This driver supports HDMI 2.0 version. -+ -+ To compile this driver as a module, choose M here. The module -+ will be called synopsys_hdmirx. -+ -+config VIDEO_SYNOPSYS_HDMIRX_LOAD_DEFAULT_EDID -+ bool "Load default EDID" -+ depends on VIDEO_SYNOPSYS_HDMIRX -+ help -+ Preload default EDID (Extended Display Identification Data). -+ EDID contains information about the capabilities of the display, -+ such as supported resolutions, refresh rates, and audio formats. -+ -+ Enabling this option is recommended for a non-production use-cases. -diff --git a/drivers/media/platform/synopsys/hdmirx/Makefile b/drivers/media/platform/synopsys/hdmirx/Makefile -new file mode 100644 -index 000000000000..2fa2d9e25300 ---- /dev/null -+++ b/drivers/media/platform/synopsys/hdmirx/Makefile -@@ -0,0 +1,4 @@ -+# SPDX-License-Identifier: GPL-2.0 -+synopsys-hdmirx-objs := snps_hdmirx.o snps_hdmirx_cec.o -+ -+obj-$(CONFIG_VIDEO_SYNOPSYS_HDMIRX) += synopsys-hdmirx.o -diff --git a/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c b/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c -new file mode 100644 -index 000000000000..7b530b134c2d ---- /dev/null -+++ b/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c -@@ -0,0 +1,2663 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2024 Collabora, Ltd. -+ * Author: Shreeya Patel <shreeya.patel@collabora.com> -+ * -+ * Copyright (c) 2021 Rockchip Electronics Co. Ltd. -+ * Author: Dingxian Wen <shawn.wen@rock-chips.com> -+ */ -+ -+#include <linux/clk.h> -+#include <linux/completion.h> -+#include <linux/delay.h> -+#include <linux/dma-mapping.h> -+#include <linux/gpio/consumer.h> -+#include <linux/hdmi.h> -+#include <linux/interrupt.h> -+#include <linux/irq.h> -+#include <linux/mfd/syscon.h> -+#include <linux/module.h> -+#include <linux/of.h> -+#include <linux/of_platform.h> -+#include <linux/of_reserved_mem.h> -+#include <linux/pinctrl/consumer.h> -+#include <linux/platform_device.h> -+#include <linux/property.h> -+#include <linux/regmap.h> -+#include <linux/reset.h> -+#include <linux/v4l2-dv-timings.h> -+#include <linux/workqueue.h> -+ -+#include <media/cec.h> -+#include <media/cec-notifier.h> -+#include <media/v4l2-common.h> -+#include <media/v4l2-ctrls.h> -+#include <media/v4l2-device.h> -+#include <media/v4l2-dv-timings.h> -+#include <media/v4l2-event.h> -+#include <media/v4l2-fh.h> -+#include <media/v4l2-ioctl.h> -+#include <media/videobuf2-dma-contig.h> -+#include <media/videobuf2-v4l2.h> -+#include <media/v4l2-common.h> -+ -+#include <sound/hdmi-codec.h> -+ -+#include "snps_hdmirx.h" -+#include "snps_hdmirx_cec.h" -+ -+#define EDID_NUM_BLOCKS_MAX 2 -+#define EDID_BLOCK_SIZE 128 -+#define HDMIRX_PLANE_Y 0 -+#define HDMIRX_PLANE_CBCR 1 -+#define FILTER_FRAME_CNT 6 -+ -+static int debug; -+module_param(debug, int, 0644); -+MODULE_PARM_DESC(debug, "debug level (0-3)"); -+ -+enum hdmirx_pix_fmt { -+ HDMIRX_RGB888 = 0, -+ HDMIRX_YUV422 = 1, -+ HDMIRX_YUV444 = 2, -+ HDMIRX_YUV420 = 3, -+}; -+ -+enum ddr_store_fmt { -+ STORE_RGB888 = 0, -+ STORE_RGBA_ARGB, -+ STORE_YUV420_8BIT, -+ STORE_YUV420_10BIT, -+ STORE_YUV422_8BIT, -+ STORE_YUV422_10BIT, -+ STORE_YUV444_8BIT, -+ STORE_YUV420_16BIT = 8, -+ STORE_YUV422_16BIT = 9, -+}; -+ -+enum hdmirx_reg_attr { -+ HDMIRX_ATTR_RW = 0, -+ HDMIRX_ATTR_RO = 1, -+ HDMIRX_ATTR_WO = 2, -+ HDMIRX_ATTR_RE = 3, -+}; -+ -+enum { -+ HDMIRX_RST_A, -+ HDMIRX_RST_P, -+ HDMIRX_RST_REF, -+ HDMIRX_RST_BIU, -+ HDMIRX_NUM_RST, -+}; -+ -+static const char * const pix_fmt_str[] = { -+ "RGB888", -+ "YUV422", -+ "YUV444", -+ "YUV420", -+}; -+ -+struct hdmirx_buffer { -+ struct vb2_v4l2_buffer vb; -+ struct list_head queue; -+ u32 buff_addr[VIDEO_MAX_PLANES]; -+}; -+ -+struct hdmirx_stream { -+ struct snps_hdmirx_dev *hdmirx_dev; -+ struct video_device vdev; -+ struct vb2_queue buf_queue; -+ struct list_head buf_head; -+ struct hdmirx_buffer *curr_buf; -+ struct hdmirx_buffer *next_buf; -+ struct v4l2_pix_format_mplane pixm; -+ const struct v4l2_format_info *out_finfo; -+ struct mutex vlock; /* to lock resources associated with video buffer and video device */ -+ spinlock_t vbq_lock; /* to lock video buffer queue */ -+ bool stopping; -+ wait_queue_head_t wq_stopped; -+ u32 frame_idx; -+ u32 line_flag_int_cnt; -+ u32 irq_stat; -+}; -+ -+struct snps_hdmirx_dev { -+ struct device *dev; -+ struct device *codec_dev; -+ struct hdmirx_stream stream; -+ struct v4l2_device v4l2_dev; -+ struct v4l2_ctrl_handler hdl; -+ struct v4l2_ctrl *detect_tx_5v_ctrl; -+ struct v4l2_ctrl *rgb_range; -+ struct v4l2_ctrl *content_type; -+ struct v4l2_dv_timings timings; -+ struct gpio_desc *detect_5v_gpio; -+ struct delayed_work delayed_work_hotplug; -+ struct delayed_work delayed_work_res_change; -+ struct cec_notifier *cec_notifier; -+ struct hdmirx_cec *cec; -+ struct mutex stream_lock; /* to lock video stream capture */ -+ struct mutex work_lock; /* to lock the critical section of hotplug event */ -+ struct reset_control_bulk_data resets[HDMIRX_NUM_RST]; -+ struct clk_bulk_data *clks; -+ struct regmap *grf; -+ struct regmap *vo1_grf; -+ struct completion cr_write_done; -+ struct completion timer_base_lock; -+ struct completion avi_pkt_rcv; -+ enum hdmirx_pix_fmt pix_fmt; -+ void __iomem *regs; -+ int hdmi_irq; -+ int dma_irq; -+ int det_irq; -+ bool hpd_trigger_level_high; -+ bool tmds_clk_ratio; -+ u32 num_clks; -+ u32 edid_blocks_written; -+ u32 cur_fmt_fourcc; -+ u32 color_depth; -+ u8 edid[EDID_BLOCK_SIZE * 2]; -+ hdmi_codec_plugged_cb plugged_cb; -+ spinlock_t rst_lock; /* to lock register access */ -+}; -+ -+static const struct v4l2_dv_timings cea640x480 = V4L2_DV_BT_CEA_640X480P59_94; -+ -+static const struct v4l2_dv_timings_cap hdmirx_timings_cap = { -+ .type = V4L2_DV_BT_656_1120, -+ .reserved = { 0 }, -+ V4L2_INIT_BT_TIMINGS(640, 4096, /* min/max width */ -+ 480, 2160, /* min/max height */ -+ 20000000, 600000000, /* min/max pixelclock */ -+ /* standards */ -+ V4L2_DV_BT_STD_CEA861, -+ /* capabilities */ -+ V4L2_DV_BT_CAP_PROGRESSIVE | -+ V4L2_DV_BT_CAP_INTERLACED) -+}; -+ -+static void hdmirx_writel(struct snps_hdmirx_dev *hdmirx_dev, int reg, u32 val) -+{ -+ guard(spinlock_irqsave)(&hdmirx_dev->rst_lock); -+ -+ writel(val, hdmirx_dev->regs + reg); -+} -+ -+static u32 hdmirx_readl(struct snps_hdmirx_dev *hdmirx_dev, int reg) -+{ -+ u32 val; -+ -+ guard(spinlock_irqsave)(&hdmirx_dev->rst_lock); -+ -+ val = readl(hdmirx_dev->regs + reg); -+ -+ return val; -+} -+ -+static void hdmirx_reset_dma(struct snps_hdmirx_dev *hdmirx_dev) -+{ -+ guard(spinlock_irqsave)(&hdmirx_dev->rst_lock); -+ -+ reset_control_reset(hdmirx_dev->resets[0].rstc); -+} -+ -+static void hdmirx_update_bits(struct snps_hdmirx_dev *hdmirx_dev, int reg, -+ u32 mask, u32 data) -+{ -+ u32 val; -+ -+ guard(spinlock_irqsave)(&hdmirx_dev->rst_lock); -+ -+ val = readl(hdmirx_dev->regs + reg) & ~mask; -+ val |= (data & mask); -+ writel(val, hdmirx_dev->regs + reg); -+} -+ -+static int hdmirx_subscribe_event(struct v4l2_fh *fh, -+ const struct v4l2_event_subscription *sub) -+{ -+ switch (sub->type) { -+ case V4L2_EVENT_SOURCE_CHANGE: -+ if (fh->vdev->vfl_dir == VFL_DIR_RX) -+ return v4l2_src_change_event_subscribe(fh, sub); -+ break; -+ case V4L2_EVENT_CTRL: -+ return v4l2_ctrl_subscribe_event(fh, sub); -+ default: -+ break; -+ } -+ -+ return -EINVAL; -+} -+ -+static bool tx_5v_power_present(struct snps_hdmirx_dev *hdmirx_dev) -+{ -+ const unsigned int detection_threshold = 7; -+ int val, i, cnt = 0; -+ bool ret; -+ -+ for (i = 0; i < 10; i++) { -+ usleep_range(1000, 1100); -+ val = gpiod_get_value(hdmirx_dev->detect_5v_gpio); -+ if (val > 0) -+ cnt++; -+ if (cnt >= detection_threshold) -+ break; -+ } -+ -+ ret = (cnt >= detection_threshold) ? true : false; -+ v4l2_dbg(3, debug, &hdmirx_dev->v4l2_dev, "%s: %d\n", __func__, ret); -+ -+ return ret; -+} -+ -+static bool signal_not_lock(struct snps_hdmirx_dev *hdmirx_dev) -+{ -+ u32 mu_status, dma_st10, cmu_st; -+ -+ mu_status = hdmirx_readl(hdmirx_dev, MAINUNIT_STATUS); -+ dma_st10 = hdmirx_readl(hdmirx_dev, DMA_STATUS10); -+ cmu_st = hdmirx_readl(hdmirx_dev, CMU_STATUS); -+ -+ if ((mu_status & TMDSVALID_STABLE_ST) && -+ (dma_st10 & HDMIRX_LOCK) && -+ (cmu_st & TMDSQPCLK_LOCKED_ST)) -+ return false; -+ -+ return true; -+} -+ -+static void hdmirx_get_timings(struct snps_hdmirx_dev *hdmirx_dev, -+ struct v4l2_bt_timings *bt) -+{ -+ struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; -+ u32 hact, vact, htotal, vtotal, fps; -+ u32 hfp, hs, hbp, vfp, vs, vbp; -+ u32 val; -+ -+ val = hdmirx_readl(hdmirx_dev, DMA_STATUS2); -+ hact = (val >> 16) & 0xffff; -+ vact = val & 0xffff; -+ -+ val = hdmirx_readl(hdmirx_dev, DMA_STATUS3); -+ htotal = (val >> 16) & 0xffff; -+ vtotal = val & 0xffff; -+ -+ val = hdmirx_readl(hdmirx_dev, DMA_STATUS4); -+ hs = (val >> 16) & 0xffff; -+ vs = val & 0xffff; -+ -+ val = hdmirx_readl(hdmirx_dev, DMA_STATUS5); -+ hbp = (val >> 16) & 0xffff; -+ vbp = val & 0xffff; -+ -+ if (hdmirx_dev->pix_fmt == HDMIRX_YUV420) { -+ htotal *= 2; -+ hbp *= 2; -+ hs *= 2; -+ } -+ -+ hfp = htotal - hact - hs - hbp; -+ vfp = vtotal - vact - vs - vbp; -+ -+ fps = (bt->pixelclock + (htotal * vtotal) / 2) / (htotal * vtotal); -+ bt->width = hact; -+ bt->height = vact; -+ bt->hfrontporch = hfp; -+ bt->hsync = hs; -+ bt->hbackporch = hbp; -+ bt->vfrontporch = vfp; -+ bt->vsync = vs; -+ bt->vbackporch = vbp; -+ -+ v4l2_dbg(1, debug, v4l2_dev, "get timings from dma\n"); -+ v4l2_dbg(1, debug, v4l2_dev, -+ "act:%ux%u%s, total:%ux%u, fps:%u, pixclk:%llu\n", -+ bt->width, bt->height, bt->interlaced ? "i" : "p", -+ htotal, vtotal, fps, bt->pixelclock); -+ -+ v4l2_dbg(2, debug, v4l2_dev, -+ "hfp:%u, hact:%u, hs:%u, hbp:%u, vfp:%u, vact:%u, vs:%u, vbp:%u\n", -+ bt->hfrontporch, hact, bt->hsync, bt->hbackporch, -+ bt->vfrontporch, vact, bt->vsync, bt->vbackporch); -+ -+ if (bt->interlaced == V4L2_DV_INTERLACED) { -+ bt->height *= 2; -+ bt->il_vfrontporch = bt->vfrontporch; -+ bt->il_vsync = bt->vsync + 1; -+ bt->il_vbackporch = bt->vbackporch; -+ } -+} -+ -+static bool hdmirx_check_timing_valid(struct v4l2_bt_timings *bt) -+{ -+ if (bt->width < 100 || bt->width > 5000 || -+ bt->height < 100 || bt->height > 5000) -+ return false; -+ -+ if (!bt->hsync || bt->hsync > 200 || -+ !bt->vsync || bt->vsync > 100) -+ return false; -+ -+ if (!bt->hbackporch || bt->hbackporch > 2000 || -+ !bt->vbackporch || bt->vbackporch > 2000) -+ return false; -+ -+ if (!bt->hfrontporch || bt->hfrontporch > 2000 || -+ !bt->vfrontporch || bt->vfrontporch > 2000) -+ return false; -+ -+ return true; -+} -+ -+static void hdmirx_toggle_polarity(struct snps_hdmirx_dev *hdmirx_dev) -+{ -+ u32 val = hdmirx_readl(hdmirx_dev, DMA_CONFIG6); -+ -+ if (!(val & (VSYNC_TOGGLE_EN | HSYNC_TOGGLE_EN))) { -+ hdmirx_update_bits(hdmirx_dev, DMA_CONFIG6, -+ VSYNC_TOGGLE_EN | HSYNC_TOGGLE_EN, -+ VSYNC_TOGGLE_EN | HSYNC_TOGGLE_EN); -+ hdmirx_update_bits(hdmirx_dev, VIDEO_CONFIG2, -+ VPROC_VSYNC_POL_OVR_VALUE | -+ VPROC_VSYNC_POL_OVR_EN | -+ VPROC_HSYNC_POL_OVR_VALUE | -+ VPROC_HSYNC_POL_OVR_EN, -+ VPROC_VSYNC_POL_OVR_EN | -+ VPROC_HSYNC_POL_OVR_EN); -+ return; -+ } -+ -+ hdmirx_update_bits(hdmirx_dev, DMA_CONFIG6, -+ VSYNC_TOGGLE_EN | HSYNC_TOGGLE_EN, 0); -+ -+ hdmirx_update_bits(hdmirx_dev, VIDEO_CONFIG2, -+ VPROC_VSYNC_POL_OVR_VALUE | -+ VPROC_VSYNC_POL_OVR_EN | -+ VPROC_HSYNC_POL_OVR_VALUE | -+ VPROC_HSYNC_POL_OVR_EN, 0); -+} -+ -+/* -+ * When querying DV timings during preview, if the DMA's timing is stable, -+ * we retrieve the timings directly from the DMA. However, if the current -+ * resolution is negative, obtaining the timing from CTRL may require a -+ * change in the sync polarity, potentially leading to DMA errors. -+ */ -+static int hdmirx_get_detected_timings(struct snps_hdmirx_dev *hdmirx_dev, -+ struct v4l2_dv_timings *timings) -+{ -+ struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; -+ struct v4l2_bt_timings *bt = &timings->bt; -+ u32 val, tmdsqpclk_freq, pix_clk; -+ u32 field_type, deframer_st; -+ u64 tmp_data, tmds_clk; -+ bool is_dvi_mode; -+ int num_retries = 0; -+ int ret; -+ -+ mutex_lock(&hdmirx_dev->work_lock); -+retry: -+ memset(timings, 0, sizeof(struct v4l2_dv_timings)); -+ timings->type = V4L2_DV_BT_656_1120; -+ -+ val = hdmirx_readl(hdmirx_dev, DMA_STATUS11); -+ field_type = (val & HDMIRX_TYPE_MASK) >> 7; -+ -+ if (field_type & BIT(0)) -+ bt->interlaced = V4L2_DV_INTERLACED; -+ else -+ bt->interlaced = V4L2_DV_PROGRESSIVE; -+ -+ deframer_st = hdmirx_readl(hdmirx_dev, DEFRAMER_STATUS); -+ is_dvi_mode = !(deframer_st & OPMODE_STS_MASK); -+ -+ tmdsqpclk_freq = hdmirx_readl(hdmirx_dev, CMU_TMDSQPCLK_FREQ); -+ tmds_clk = tmdsqpclk_freq * 4 * 1000; -+ tmp_data = tmds_clk * 24; -+ do_div(tmp_data, hdmirx_dev->color_depth); -+ pix_clk = tmp_data; -+ bt->pixelclock = pix_clk; -+ -+ if (hdmirx_dev->pix_fmt == HDMIRX_YUV420) -+ bt->pixelclock *= 2; -+ -+ hdmirx_get_timings(hdmirx_dev, bt); -+ -+ v4l2_dbg(2, debug, v4l2_dev, "tmds_clk:%llu, pix_clk:%d\n", tmds_clk, pix_clk); -+ v4l2_dbg(1, debug, v4l2_dev, "interlace:%d, fmt:%d, color:%d, mode:%s\n", -+ bt->interlaced, hdmirx_dev->pix_fmt, -+ hdmirx_dev->color_depth, -+ is_dvi_mode ? "dvi" : "hdmi"); -+ v4l2_dbg(2, debug, v4l2_dev, "deframer_st:%#x\n", deframer_st); -+ -+ /* -+ * Timing will be invalid until it's latched by HW or if signal's -+ * polarity doesn't match. -+ */ -+ if (!hdmirx_check_timing_valid(bt)) { -+ if (num_retries++ < 20) { -+ if (num_retries == 10) -+ hdmirx_toggle_polarity(hdmirx_dev); -+ -+ usleep_range(10 * 1000, 10 * 1100); -+ goto retry; -+ } -+ -+ ret = -ERANGE; -+ } else { -+ ret = 0; -+ } -+ -+ mutex_unlock(&hdmirx_dev->work_lock); -+ -+ return ret; -+} -+ -+static bool port_no_link(struct snps_hdmirx_dev *hdmirx_dev) -+{ -+ return !tx_5v_power_present(hdmirx_dev); -+} -+ -+static int hdmirx_query_dv_timings(struct file *file, void *_fh, -+ struct v4l2_dv_timings *timings) -+{ -+ struct hdmirx_stream *stream = video_drvdata(file); -+ struct snps_hdmirx_dev *hdmirx_dev = stream->hdmirx_dev; -+ struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; -+ int ret; -+ -+ if (port_no_link(hdmirx_dev)) { -+ v4l2_err(v4l2_dev, "%s: port has no link\n", __func__); -+ return -ENOLINK; -+ } -+ -+ if (signal_not_lock(hdmirx_dev)) { -+ v4l2_err(v4l2_dev, "%s: signal is not locked\n", __func__); -+ return -ENOLCK; -+ } -+ -+ ret = hdmirx_get_detected_timings(hdmirx_dev, timings); -+ if (ret) -+ return ret; -+ -+ if (debug) -+ v4l2_print_dv_timings(hdmirx_dev->v4l2_dev.name, -+ "query_dv_timings: ", timings, false); -+ -+ if (!v4l2_valid_dv_timings(timings, &hdmirx_timings_cap, NULL, NULL)) { -+ v4l2_dbg(1, debug, v4l2_dev, "%s: timings out of range\n", __func__); -+ return -ERANGE; -+ } -+ -+ return 0; -+} -+ -+static void hdmirx_hpd_ctrl(struct snps_hdmirx_dev *hdmirx_dev, bool en) -+{ -+ struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; -+ -+ v4l2_dbg(1, debug, v4l2_dev, "%s: %sable, hpd_trigger_level_high:%d\n", -+ __func__, en ? "en" : "dis", -+ hdmirx_dev->hpd_trigger_level_high); -+ -+ hdmirx_update_bits(hdmirx_dev, SCDC_CONFIG, HPDLOW, en ? 0 : HPDLOW); -+ en = hdmirx_dev->hpd_trigger_level_high ? en : !en; -+ hdmirx_writel(hdmirx_dev, CORE_CONFIG, en); -+} -+ -+static void hdmirx_write_edid(struct snps_hdmirx_dev *hdmirx_dev, -+ struct v4l2_edid *edid) -+{ -+ u32 edid_len = edid->blocks * EDID_BLOCK_SIZE; -+ char data[300]; -+ u32 i; -+ -+ memset(edid->reserved, 0, sizeof(edid->reserved)); -+ -+ cec_s_phys_addr_from_edid(hdmirx_dev->cec->adap, -+ (const struct edid *)edid->edid); -+ -+ memset(&hdmirx_dev->edid, 0, sizeof(hdmirx_dev->edid)); -+ hdmirx_update_bits(hdmirx_dev, DMA_CONFIG11, -+ EDID_READ_EN_MASK | -+ EDID_WRITE_EN_MASK | -+ EDID_SLAVE_ADDR_MASK, -+ EDID_READ_EN(0) | -+ EDID_WRITE_EN(1) | -+ EDID_SLAVE_ADDR(0x50)); -+ for (i = 0; i < edid_len; i++) -+ hdmirx_writel(hdmirx_dev, DMA_CONFIG10, edid->edid[i]); -+ -+ /* read out for debug */ -+ if (debug >= 2) { -+ hdmirx_update_bits(hdmirx_dev, DMA_CONFIG11, -+ EDID_READ_EN_MASK | -+ EDID_WRITE_EN_MASK, -+ EDID_READ_EN(1) | -+ EDID_WRITE_EN(0)); -+ edid_len = edid_len > sizeof(data) ? sizeof(data) : edid_len; -+ memset(data, 0, sizeof(data)); -+ for (i = 0; i < edid_len; i++) -+ data[i] = hdmirx_readl(hdmirx_dev, DMA_STATUS14); -+ -+ print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1, data, -+ edid_len, false); -+ } -+ -+ /* -+ * You must set EDID_READ_EN & EDID_WRITE_EN bit to 0, -+ * when the read/write edid operation is completed.Otherwise, it -+ * will affect the reading and writing of other registers -+ */ -+ hdmirx_update_bits(hdmirx_dev, DMA_CONFIG11, -+ EDID_READ_EN_MASK | EDID_WRITE_EN_MASK, -+ EDID_READ_EN(0) | EDID_WRITE_EN(0)); -+ -+ hdmirx_dev->edid_blocks_written = edid->blocks; -+ memcpy(&hdmirx_dev->edid, edid->edid, edid->blocks * EDID_BLOCK_SIZE); -+} -+ -+/* -+ * Before clearing interrupt, we need to read the interrupt status. -+ */ -+static inline void hdmirx_clear_interrupt(struct snps_hdmirx_dev *hdmirx_dev, -+ u32 reg, u32 val) -+{ -+ /* (interrupt status register) = (interrupt clear register) - 0x8 */ -+ hdmirx_readl(hdmirx_dev, reg - 0x8); -+ hdmirx_writel(hdmirx_dev, reg, val); -+} -+ -+static void hdmirx_interrupts_setup(struct snps_hdmirx_dev *hdmirx_dev, bool en) -+{ -+ v4l2_dbg(1, debug, &hdmirx_dev->v4l2_dev, "%s: %sable\n", -+ __func__, en ? "en" : "dis"); -+ -+ disable_irq(hdmirx_dev->hdmi_irq); -+ -+ /* Note: In DVI mode, it needs to be written twice to take effect. */ -+ hdmirx_clear_interrupt(hdmirx_dev, MAINUNIT_0_INT_CLEAR, 0xffffffff); -+ hdmirx_clear_interrupt(hdmirx_dev, MAINUNIT_2_INT_CLEAR, 0xffffffff); -+ hdmirx_clear_interrupt(hdmirx_dev, MAINUNIT_0_INT_CLEAR, 0xffffffff); -+ hdmirx_clear_interrupt(hdmirx_dev, MAINUNIT_2_INT_CLEAR, 0xffffffff); -+ hdmirx_clear_interrupt(hdmirx_dev, AVPUNIT_0_INT_CLEAR, 0xffffffff); -+ -+ if (en) { -+ hdmirx_update_bits(hdmirx_dev, MAINUNIT_0_INT_MASK_N, -+ TMDSQPCLK_OFF_CHG | TMDSQPCLK_LOCKED_CHG, -+ TMDSQPCLK_OFF_CHG | TMDSQPCLK_LOCKED_CHG); -+ hdmirx_update_bits(hdmirx_dev, MAINUNIT_2_INT_MASK_N, -+ TMDSVALID_STABLE_CHG, TMDSVALID_STABLE_CHG); -+ hdmirx_update_bits(hdmirx_dev, AVPUNIT_0_INT_MASK_N, -+ CED_DYN_CNT_CH2_IRQ | -+ CED_DYN_CNT_CH1_IRQ | -+ CED_DYN_CNT_CH0_IRQ, -+ CED_DYN_CNT_CH2_IRQ | -+ CED_DYN_CNT_CH1_IRQ | -+ CED_DYN_CNT_CH0_IRQ); -+ } else { -+ hdmirx_writel(hdmirx_dev, MAINUNIT_0_INT_MASK_N, 0); -+ hdmirx_writel(hdmirx_dev, MAINUNIT_2_INT_MASK_N, 0); -+ hdmirx_writel(hdmirx_dev, AVPUNIT_0_INT_MASK_N, 0); -+ } -+ -+ enable_irq(hdmirx_dev->hdmi_irq); -+} -+ -+static void hdmirx_plugout(struct snps_hdmirx_dev *hdmirx_dev) -+{ -+ hdmirx_update_bits(hdmirx_dev, SCDC_CONFIG, POWERPROVIDED, 0); -+ hdmirx_interrupts_setup(hdmirx_dev, false); -+ hdmirx_hpd_ctrl(hdmirx_dev, false); -+ hdmirx_update_bits(hdmirx_dev, DMA_CONFIG6, HDMIRX_DMA_EN, 0); -+ hdmirx_update_bits(hdmirx_dev, DMA_CONFIG4, -+ LINE_FLAG_INT_EN | -+ HDMIRX_DMA_IDLE_INT | -+ HDMIRX_LOCK_DISABLE_INT | -+ LAST_FRAME_AXI_UNFINISH_INT_EN | -+ FIFO_OVERFLOW_INT_EN | -+ FIFO_UNDERFLOW_INT_EN | -+ HDMIRX_AXI_ERROR_INT_EN, 0); -+ hdmirx_reset_dma(hdmirx_dev); -+ hdmirx_update_bits(hdmirx_dev, PHY_CONFIG, HDMI_DISABLE | PHY_RESET | -+ PHY_PDDQ, HDMI_DISABLE); -+ hdmirx_writel(hdmirx_dev, PHYCREG_CONFIG0, 0x0); -+ cancel_delayed_work(&hdmirx_dev->delayed_work_res_change); -+ -+ v4l2_ctrl_s_ctrl(hdmirx_dev->rgb_range, V4L2_DV_RGB_RANGE_AUTO); -+ v4l2_ctrl_s_ctrl(hdmirx_dev->content_type, V4L2_DV_IT_CONTENT_TYPE_NO_ITC); -+} -+ -+static int hdmirx_set_edid(struct file *file, void *fh, struct v4l2_edid *edid) -+{ -+ struct hdmirx_stream *stream = video_drvdata(file); -+ struct snps_hdmirx_dev *hdmirx_dev = stream->hdmirx_dev; -+ u16 phys_addr; -+ int ret; -+ -+ if (edid->pad) -+ return -EINVAL; -+ -+ if (edid->start_block) -+ return -EINVAL; -+ -+ if (edid->blocks > EDID_NUM_BLOCKS_MAX) { -+ edid->blocks = EDID_NUM_BLOCKS_MAX; -+ return -E2BIG; -+ } -+ -+ if (!edid->blocks) { -+ cec_phys_addr_invalidate(hdmirx_dev->cec->adap); -+ hdmirx_dev->edid_blocks_written = 0; -+ return 0; -+ } -+ -+ phys_addr = cec_get_edid_phys_addr(edid->edid, edid->blocks * 128, NULL); -+ ret = v4l2_phys_addr_validate(phys_addr, &phys_addr, NULL); -+ if (ret) -+ return ret; -+ -+ disable_irq(hdmirx_dev->hdmi_irq); -+ disable_irq(hdmirx_dev->dma_irq); -+ -+ if (tx_5v_power_present(hdmirx_dev)) -+ hdmirx_plugout(hdmirx_dev); -+ -+ hdmirx_hpd_ctrl(hdmirx_dev, false); -+ hdmirx_write_edid(hdmirx_dev, edid); -+ -+ enable_irq(hdmirx_dev->hdmi_irq); -+ enable_irq(hdmirx_dev->dma_irq); -+ -+ queue_delayed_work(system_unbound_wq, -+ &hdmirx_dev->delayed_work_hotplug, -+ msecs_to_jiffies(110)); -+ return 0; -+} -+ -+static int hdmirx_get_edid(struct file *file, void *fh, struct v4l2_edid *edid) -+{ -+ struct hdmirx_stream *stream = video_drvdata(file); -+ struct snps_hdmirx_dev *hdmirx_dev = stream->hdmirx_dev; -+ struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; -+ -+ memset(edid->reserved, 0, sizeof(edid->reserved)); -+ -+ if (edid->pad) -+ return -EINVAL; -+ -+ if (!edid->start_block && !edid->blocks) { -+ edid->blocks = hdmirx_dev->edid_blocks_written; -+ return 0; -+ } -+ -+ if (!hdmirx_dev->edid_blocks_written) -+ return -ENODATA; -+ -+ if (edid->start_block >= hdmirx_dev->edid_blocks_written || !edid->blocks) -+ return -EINVAL; -+ -+ if (edid->start_block + edid->blocks > hdmirx_dev->edid_blocks_written) -+ edid->blocks = hdmirx_dev->edid_blocks_written - edid->start_block; -+ -+ memcpy(edid->edid, &hdmirx_dev->edid, edid->blocks * EDID_BLOCK_SIZE); -+ -+ v4l2_dbg(1, debug, v4l2_dev, "%s: read EDID:\n", __func__); -+ if (debug > 0) -+ print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1, -+ edid->edid, edid->blocks * EDID_BLOCK_SIZE, false); -+ -+ return 0; -+} -+ -+static int hdmirx_g_parm(struct file *file, void *priv, -+ struct v4l2_streamparm *parm) -+{ -+ struct hdmirx_stream *stream = video_drvdata(file); -+ struct snps_hdmirx_dev *hdmirx_dev = stream->hdmirx_dev; -+ struct v4l2_fract fps; -+ -+ if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) -+ return -EINVAL; -+ -+ fps = v4l2_calc_timeperframe(&hdmirx_dev->timings); -+ parm->parm.capture.timeperframe.numerator = fps.numerator; -+ parm->parm.capture.timeperframe.denominator = fps.denominator; -+ -+ return 0; -+} -+ -+static int hdmirx_dv_timings_cap(struct file *file, void *fh, -+ struct v4l2_dv_timings_cap *cap) -+{ -+ *cap = hdmirx_timings_cap; -+ return 0; -+} -+ -+static int hdmirx_enum_dv_timings(struct file *file, void *_fh, -+ struct v4l2_enum_dv_timings *timings) -+{ -+ return v4l2_enum_dv_timings_cap(timings, &hdmirx_timings_cap, NULL, NULL); -+} -+ -+static void hdmirx_scdc_init(struct snps_hdmirx_dev *hdmirx_dev) -+{ -+ hdmirx_update_bits(hdmirx_dev, I2C_SLAVE_CONFIG1, -+ I2C_SDA_OUT_HOLD_VALUE_QST_MASK | -+ I2C_SDA_IN_HOLD_VALUE_QST_MASK, -+ I2C_SDA_OUT_HOLD_VALUE_QST(0x80) | -+ I2C_SDA_IN_HOLD_VALUE_QST(0x15)); -+ hdmirx_update_bits(hdmirx_dev, SCDC_REGBANK_CONFIG0, -+ SCDC_SINKVERSION_QST_MASK, -+ SCDC_SINKVERSION_QST(1)); -+} -+ -+static int wait_reg_bit_status(struct snps_hdmirx_dev *hdmirx_dev, u32 reg, -+ u32 bit_mask, u32 expect_val, bool is_grf, -+ u32 ms) -+{ -+ struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; -+ u32 i, val; -+ -+ for (i = 0; i < ms; i++) { -+ if (is_grf) -+ regmap_read(hdmirx_dev->grf, reg, &val); -+ else -+ val = hdmirx_readl(hdmirx_dev, reg); -+ -+ if ((val & bit_mask) == expect_val) { -+ v4l2_dbg(2, debug, v4l2_dev, -+ "%s: i:%d, time: %dms\n", __func__, i, ms); -+ break; -+ } -+ usleep_range(1000, 1010); -+ } -+ -+ if (i == ms) -+ return -1; -+ -+ return 0; -+} -+ -+static int hdmirx_phy_register_write(struct snps_hdmirx_dev *hdmirx_dev, -+ u32 phy_reg, u32 val) -+{ -+ struct device *dev = hdmirx_dev->dev; -+ -+ reinit_completion(&hdmirx_dev->cr_write_done); -+ /* clear irq status */ -+ hdmirx_clear_interrupt(hdmirx_dev, MAINUNIT_2_INT_CLEAR, 0xffffffff); -+ /* en irq */ -+ hdmirx_update_bits(hdmirx_dev, MAINUNIT_2_INT_MASK_N, -+ PHYCREG_CR_WRITE_DONE, PHYCREG_CR_WRITE_DONE); -+ /* write phy reg addr */ -+ hdmirx_writel(hdmirx_dev, PHYCREG_CONFIG1, phy_reg); -+ /* write phy reg val */ -+ hdmirx_writel(hdmirx_dev, PHYCREG_CONFIG2, val); -+ /* config write enable */ -+ hdmirx_writel(hdmirx_dev, PHYCREG_CONTROL, PHYCREG_CR_PARA_WRITE_P); -+ -+ if (!wait_for_completion_timeout(&hdmirx_dev->cr_write_done, -+ msecs_to_jiffies(20))) { -+ dev_err(dev, "%s wait cr write done failed\n", __func__); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static void hdmirx_tmds_clk_ratio_config(struct snps_hdmirx_dev *hdmirx_dev) -+{ -+ struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; -+ u32 val; -+ -+ val = hdmirx_readl(hdmirx_dev, SCDC_REGBANK_STATUS1); -+ v4l2_dbg(3, debug, v4l2_dev, "%s: scdc_regbank_st:%#x\n", __func__, val); -+ hdmirx_dev->tmds_clk_ratio = (val & SCDC_TMDSBITCLKRATIO) > 0; -+ -+ if (hdmirx_dev->tmds_clk_ratio) { -+ v4l2_dbg(3, debug, v4l2_dev, "%s: HDMITX greater than 3.4Gbps\n", __func__); -+ hdmirx_update_bits(hdmirx_dev, PHY_CONFIG, -+ TMDS_CLOCK_RATIO, TMDS_CLOCK_RATIO); -+ } else { -+ v4l2_dbg(3, debug, v4l2_dev, "%s: HDMITX less than 3.4Gbps\n", __func__); -+ hdmirx_update_bits(hdmirx_dev, PHY_CONFIG, -+ TMDS_CLOCK_RATIO, 0); -+ } -+} -+ -+static void hdmirx_phy_config(struct snps_hdmirx_dev *hdmirx_dev) -+{ -+ struct device *dev = hdmirx_dev->dev; -+ -+ hdmirx_clear_interrupt(hdmirx_dev, SCDC_INT_CLEAR, 0xffffffff); -+ hdmirx_update_bits(hdmirx_dev, SCDC_INT_MASK_N, SCDCTMDSCCFG_CHG, -+ SCDCTMDSCCFG_CHG); -+ /* cr_para_clk 24M */ -+ hdmirx_update_bits(hdmirx_dev, PHY_CONFIG, REFFREQ_SEL_MASK, REFFREQ_SEL(0)); -+ /* rx data width 40bit valid */ -+ hdmirx_update_bits(hdmirx_dev, PHY_CONFIG, RXDATA_WIDTH, RXDATA_WIDTH); -+ hdmirx_update_bits(hdmirx_dev, PHY_CONFIG, PHY_RESET, PHY_RESET); -+ usleep_range(100, 110); -+ hdmirx_update_bits(hdmirx_dev, PHY_CONFIG, PHY_RESET, 0); -+ usleep_range(100, 110); -+ /* select cr para interface */ -+ hdmirx_writel(hdmirx_dev, PHYCREG_CONFIG0, 0x3); -+ -+ if (wait_reg_bit_status(hdmirx_dev, SYS_GRF_SOC_STATUS1, -+ HDMIRXPHY_SRAM_INIT_DONE, -+ HDMIRXPHY_SRAM_INIT_DONE, true, 10)) -+ dev_err(dev, "%s: phy SRAM init failed\n", __func__); -+ -+ regmap_write(hdmirx_dev->grf, SYS_GRF_SOC_CON1, -+ (HDMIRXPHY_SRAM_EXT_LD_DONE << 16) | -+ HDMIRXPHY_SRAM_EXT_LD_DONE); -+ hdmirx_phy_register_write(hdmirx_dev, SUP_DIG_ANA_CREGS_SUP_ANA_NC, 2); -+ hdmirx_phy_register_write(hdmirx_dev, SUP_DIG_ANA_CREGS_SUP_ANA_NC, 3); -+ hdmirx_phy_register_write(hdmirx_dev, SUP_DIG_ANA_CREGS_SUP_ANA_NC, 2); -+ hdmirx_phy_register_write(hdmirx_dev, SUP_DIG_ANA_CREGS_SUP_ANA_NC, 2); -+ hdmirx_phy_register_write(hdmirx_dev, SUP_DIG_ANA_CREGS_SUP_ANA_NC, 3); -+ hdmirx_phy_register_write(hdmirx_dev, SUP_DIG_ANA_CREGS_SUP_ANA_NC, 2); -+ hdmirx_phy_register_write(hdmirx_dev, SUP_DIG_ANA_CREGS_SUP_ANA_NC, 0); -+ hdmirx_phy_register_write(hdmirx_dev, SUP_DIG_ANA_CREGS_SUP_ANA_NC, 1); -+ hdmirx_phy_register_write(hdmirx_dev, SUP_DIG_ANA_CREGS_SUP_ANA_NC, 0); -+ hdmirx_phy_register_write(hdmirx_dev, SUP_DIG_ANA_CREGS_SUP_ANA_NC, 0); -+ -+ hdmirx_phy_register_write(hdmirx_dev, -+ HDMIPCS_DIG_CTRL_PATH_MAIN_FSM_RATE_CALC_HDMI14_CDR_SETTING_3_REG, -+ CDR_SETTING_BOUNDARY_3_DEFAULT); -+ hdmirx_phy_register_write(hdmirx_dev, -+ HDMIPCS_DIG_CTRL_PATH_MAIN_FSM_RATE_CALC_HDMI14_CDR_SETTING_4_REG, -+ CDR_SETTING_BOUNDARY_4_DEFAULT); -+ hdmirx_phy_register_write(hdmirx_dev, -+ HDMIPCS_DIG_CTRL_PATH_MAIN_FSM_RATE_CALC_HDMI14_CDR_SETTING_5_REG, -+ CDR_SETTING_BOUNDARY_5_DEFAULT); -+ hdmirx_phy_register_write(hdmirx_dev, -+ HDMIPCS_DIG_CTRL_PATH_MAIN_FSM_RATE_CALC_HDMI14_CDR_SETTING_6_REG, -+ CDR_SETTING_BOUNDARY_6_DEFAULT); -+ hdmirx_phy_register_write(hdmirx_dev, -+ HDMIPCS_DIG_CTRL_PATH_MAIN_FSM_RATE_CALC_HDMI14_CDR_SETTING_7_REG, -+ CDR_SETTING_BOUNDARY_7_DEFAULT); -+ -+ hdmirx_update_bits(hdmirx_dev, PHY_CONFIG, PHY_PDDQ, 0); -+ if (wait_reg_bit_status(hdmirx_dev, PHY_STATUS, PDDQ_ACK, 0, false, 10)) -+ dev_err(dev, "%s: wait pddq ack failed\n", __func__); -+ -+ hdmirx_update_bits(hdmirx_dev, PHY_CONFIG, HDMI_DISABLE, 0); -+ if (wait_reg_bit_status(hdmirx_dev, PHY_STATUS, HDMI_DISABLE_ACK, 0, -+ false, 50)) -+ dev_err(dev, "%s: wait hdmi disable ack failed\n", __func__); -+ -+ hdmirx_tmds_clk_ratio_config(hdmirx_dev); -+} -+ -+static void hdmirx_controller_init(struct snps_hdmirx_dev *hdmirx_dev) -+{ -+ const unsigned long iref_clk_freq_hz = 428571429; -+ struct device *dev = hdmirx_dev->dev; -+ -+ reinit_completion(&hdmirx_dev->timer_base_lock); -+ hdmirx_clear_interrupt(hdmirx_dev, MAINUNIT_0_INT_CLEAR, 0xffffffff); -+ /* en irq */ -+ hdmirx_update_bits(hdmirx_dev, MAINUNIT_0_INT_MASK_N, -+ TIMER_BASE_LOCKED_IRQ, TIMER_BASE_LOCKED_IRQ); -+ /* write irefclk freq */ -+ hdmirx_writel(hdmirx_dev, GLOBAL_TIMER_REF_BASE, iref_clk_freq_hz); -+ -+ if (!wait_for_completion_timeout(&hdmirx_dev->timer_base_lock, -+ msecs_to_jiffies(20))) -+ dev_err(dev, "%s wait timer base lock failed\n", __func__); -+ -+ hdmirx_update_bits(hdmirx_dev, CMU_CONFIG0, -+ TMDSQPCLK_STABLE_FREQ_MARGIN_MASK | -+ AUDCLK_STABLE_FREQ_MARGIN_MASK, -+ TMDSQPCLK_STABLE_FREQ_MARGIN(2) | -+ AUDCLK_STABLE_FREQ_MARGIN(1)); -+ hdmirx_update_bits(hdmirx_dev, DESCRAND_EN_CONTROL, -+ SCRAMB_EN_SEL_QST_MASK, SCRAMB_EN_SEL_QST(1)); -+ hdmirx_update_bits(hdmirx_dev, CED_CONFIG, -+ CED_VIDDATACHECKEN_QST | -+ CED_DATAISCHECKEN_QST | -+ CED_GBCHECKEN_QST | -+ CED_CTRLCHECKEN_QST | -+ CED_CHLOCKMAXER_QST_MASK, -+ CED_VIDDATACHECKEN_QST | -+ CED_GBCHECKEN_QST | -+ CED_CTRLCHECKEN_QST | -+ CED_CHLOCKMAXER_QST(0x10)); -+ hdmirx_update_bits(hdmirx_dev, DEFRAMER_CONFIG0, -+ VS_REMAPFILTER_EN_QST | VS_FILTER_ORDER_QST_MASK, -+ VS_REMAPFILTER_EN_QST | VS_FILTER_ORDER_QST(0x3)); -+} -+ -+static void hdmirx_get_colordepth(struct snps_hdmirx_dev *hdmirx_dev) -+{ -+ struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; -+ u32 val, color_depth_reg; -+ -+ val = hdmirx_readl(hdmirx_dev, DMA_STATUS11); -+ color_depth_reg = (val & HDMIRX_COLOR_DEPTH_MASK) >> 3; -+ -+ switch (color_depth_reg) { -+ case 0x4: -+ hdmirx_dev->color_depth = 24; -+ break; -+ case 0x5: -+ hdmirx_dev->color_depth = 30; -+ break; -+ case 0x6: -+ hdmirx_dev->color_depth = 36; -+ break; -+ case 0x7: -+ hdmirx_dev->color_depth = 48; -+ break; -+ default: -+ hdmirx_dev->color_depth = 24; -+ break; -+ } -+ -+ v4l2_dbg(1, debug, v4l2_dev, "%s: color_depth: %d, reg_val:%d\n", -+ __func__, hdmirx_dev->color_depth, color_depth_reg); -+} -+ -+static void hdmirx_get_pix_fmt(struct snps_hdmirx_dev *hdmirx_dev) -+{ -+ struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; -+ u32 val; -+ -+ val = hdmirx_readl(hdmirx_dev, DMA_STATUS11); -+ hdmirx_dev->pix_fmt = val & HDMIRX_FORMAT_MASK; -+ -+ switch (hdmirx_dev->pix_fmt) { -+ case HDMIRX_RGB888: -+ hdmirx_dev->cur_fmt_fourcc = V4L2_PIX_FMT_BGR24; -+ break; -+ case HDMIRX_YUV422: -+ hdmirx_dev->cur_fmt_fourcc = V4L2_PIX_FMT_NV16; -+ break; -+ case HDMIRX_YUV444: -+ hdmirx_dev->cur_fmt_fourcc = V4L2_PIX_FMT_NV24; -+ break; -+ case HDMIRX_YUV420: -+ hdmirx_dev->cur_fmt_fourcc = V4L2_PIX_FMT_NV12; -+ break; -+ default: -+ v4l2_err(v4l2_dev, -+ "%s: err pix_fmt: %d, set RGB888 as default\n", -+ __func__, hdmirx_dev->pix_fmt); -+ hdmirx_dev->pix_fmt = HDMIRX_RGB888; -+ hdmirx_dev->cur_fmt_fourcc = V4L2_PIX_FMT_BGR24; -+ break; -+ } -+ -+ v4l2_dbg(1, debug, v4l2_dev, "%s: pix_fmt: %s\n", __func__, -+ pix_fmt_str[hdmirx_dev->pix_fmt]); -+} -+ -+static void hdmirx_get_avi_infoframe(struct snps_hdmirx_dev *hdmirx_dev) -+{ -+ struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; -+ union hdmi_infoframe frame = {}; -+ int err, i, b, itr = 0; -+ u8 aviif[3 + 7 * 4]; -+ u32 val; -+ -+ aviif[itr++] = HDMI_INFOFRAME_TYPE_AVI; -+ val = hdmirx_readl(hdmirx_dev, PKTDEC_AVIIF_PH2_1); -+ aviif[itr++] = val & 0xff; -+ aviif[itr++] = (val >> 8) & 0xff; -+ -+ for (i = 0; i < 7; i++) { -+ val = hdmirx_readl(hdmirx_dev, PKTDEC_AVIIF_PB3_0 + 4 * i); -+ -+ for (b = 0; b < 4; b++) -+ aviif[itr++] = (val >> (8 * b)) & 0xff; -+ } -+ -+ err = hdmi_infoframe_unpack(&frame, aviif, sizeof(aviif)); -+ if (err) { -+ v4l2_err(v4l2_dev, "failed to unpack AVI infoframe\n"); -+ return; -+ } -+ -+ v4l2_ctrl_s_ctrl(hdmirx_dev->rgb_range, frame.avi.quantization_range); -+ -+ if (frame.avi.itc) -+ v4l2_ctrl_s_ctrl(hdmirx_dev->content_type, -+ frame.avi.content_type); -+ else -+ v4l2_ctrl_s_ctrl(hdmirx_dev->content_type, -+ V4L2_DV_IT_CONTENT_TYPE_NO_ITC); -+} -+ -+static void hdmirx_format_change(struct snps_hdmirx_dev *hdmirx_dev) -+{ -+ struct hdmirx_stream *stream = &hdmirx_dev->stream; -+ struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; -+ static const struct v4l2_event ev_src_chg = { -+ .type = V4L2_EVENT_SOURCE_CHANGE, -+ .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION, -+ }; -+ -+ hdmirx_get_pix_fmt(hdmirx_dev); -+ hdmirx_get_colordepth(hdmirx_dev); -+ hdmirx_get_avi_infoframe(hdmirx_dev); -+ -+ v4l2_dbg(1, debug, v4l2_dev, "%s: queue res_chg_event\n", __func__); -+ v4l2_event_queue(&stream->vdev, &ev_src_chg); -+} -+ -+static void hdmirx_set_ddr_store_fmt(struct snps_hdmirx_dev *hdmirx_dev) -+{ -+ struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; -+ enum ddr_store_fmt store_fmt; -+ u32 dma_cfg1; -+ -+ switch (hdmirx_dev->pix_fmt) { -+ case HDMIRX_RGB888: -+ store_fmt = STORE_RGB888; -+ break; -+ case HDMIRX_YUV444: -+ store_fmt = STORE_YUV444_8BIT; -+ break; -+ case HDMIRX_YUV422: -+ store_fmt = STORE_YUV422_8BIT; -+ break; -+ case HDMIRX_YUV420: -+ store_fmt = STORE_YUV420_8BIT; -+ break; -+ default: -+ store_fmt = STORE_RGB888; -+ break; -+ } -+ -+ hdmirx_update_bits(hdmirx_dev, DMA_CONFIG1, -+ DDR_STORE_FORMAT_MASK, DDR_STORE_FORMAT(store_fmt)); -+ dma_cfg1 = hdmirx_readl(hdmirx_dev, DMA_CONFIG1); -+ v4l2_dbg(1, debug, v4l2_dev, "%s: pix_fmt: %s, DMA_CONFIG1:%#x\n", -+ __func__, pix_fmt_str[hdmirx_dev->pix_fmt], dma_cfg1); -+} -+ -+static void hdmirx_dma_config(struct snps_hdmirx_dev *hdmirx_dev) -+{ -+ hdmirx_set_ddr_store_fmt(hdmirx_dev); -+ -+ /* Note: uv_swap, rb can not swap, doc err */ -+ if (hdmirx_dev->cur_fmt_fourcc != V4L2_PIX_FMT_NV16) -+ hdmirx_update_bits(hdmirx_dev, DMA_CONFIG6, RB_SWAP_EN, RB_SWAP_EN); -+ else -+ hdmirx_update_bits(hdmirx_dev, DMA_CONFIG6, RB_SWAP_EN, 0); -+ -+ hdmirx_update_bits(hdmirx_dev, DMA_CONFIG7, -+ LOCK_FRAME_NUM_MASK, -+ LOCK_FRAME_NUM(2)); -+ hdmirx_update_bits(hdmirx_dev, DMA_CONFIG1, -+ UV_WID_MASK | Y_WID_MASK | ABANDON_EN, -+ UV_WID(1) | Y_WID(2) | ABANDON_EN); -+} -+ -+static void hdmirx_submodule_init(struct snps_hdmirx_dev *hdmirx_dev) -+{ -+ /* Note: if not config HDCP2_CONFIG, there will be some errors; */ -+ hdmirx_update_bits(hdmirx_dev, HDCP2_CONFIG, -+ HDCP2_SWITCH_OVR_VALUE | -+ HDCP2_SWITCH_OVR_EN, -+ HDCP2_SWITCH_OVR_EN); -+ hdmirx_scdc_init(hdmirx_dev); -+ hdmirx_controller_init(hdmirx_dev); -+} -+ -+static int hdmirx_enum_input(struct file *file, void *priv, -+ struct v4l2_input *input) -+{ -+ if (input->index > 0) -+ return -EINVAL; -+ -+ input->type = V4L2_INPUT_TYPE_CAMERA; -+ input->std = 0; -+ strscpy(input->name, "HDMI IN", sizeof(input->name)); -+ input->capabilities = V4L2_IN_CAP_DV_TIMINGS; -+ -+ return 0; -+} -+ -+static int hdmirx_get_input(struct file *file, void *priv, unsigned int *i) -+{ -+ *i = 0; -+ return 0; -+} -+ -+static int hdmirx_set_input(struct file *file, void *priv, unsigned int i) -+{ -+ if (i) -+ return -EINVAL; -+ return 0; -+} -+ -+static void hdmirx_set_fmt(struct hdmirx_stream *stream, -+ struct v4l2_pix_format_mplane *pixm, bool try) -+{ -+ struct snps_hdmirx_dev *hdmirx_dev = stream->hdmirx_dev; -+ struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; -+ struct v4l2_bt_timings *bt = &hdmirx_dev->timings.bt; -+ const struct v4l2_format_info *finfo; -+ unsigned int imagesize = 0; -+ int i; -+ -+ memset(&pixm->plane_fmt[0], 0, sizeof(struct v4l2_plane_pix_format)); -+ finfo = v4l2_format_info(pixm->pixelformat); -+ if (!finfo) { -+ finfo = v4l2_format_info(V4L2_PIX_FMT_BGR24); -+ v4l2_dbg(1, debug, v4l2_dev, -+ "%s: set_fmt:%#x not supported, use def_fmt:%x\n", -+ __func__, pixm->pixelformat, finfo->format); -+ } -+ -+ if (!bt->width || !bt->height) -+ v4l2_dbg(1, debug, v4l2_dev, "%s: invalid resolution:%#xx%#x\n", -+ __func__, bt->width, bt->height); -+ -+ pixm->pixelformat = finfo->format; -+ pixm->width = bt->width; -+ pixm->height = bt->height; -+ pixm->num_planes = finfo->mem_planes; -+ pixm->quantization = V4L2_QUANTIZATION_DEFAULT; -+ pixm->colorspace = V4L2_COLORSPACE_SRGB; -+ pixm->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; -+ -+ if (bt->interlaced == V4L2_DV_INTERLACED) -+ pixm->field = V4L2_FIELD_INTERLACED_TB; -+ else -+ pixm->field = V4L2_FIELD_NONE; -+ -+ memset(pixm->reserved, 0, sizeof(pixm->reserved)); -+ -+ v4l2_fill_pixfmt_mp(pixm, finfo->format, pixm->width, pixm->height); -+ -+ for (i = 0; i < finfo->comp_planes; i++) { -+ struct v4l2_plane_pix_format *plane_fmt; -+ int width, height, bpl, size, bpp = 0; -+ const unsigned int hw_align = 64; -+ -+ if (!i) { -+ width = pixm->width; -+ height = pixm->height; -+ } else { -+ width = pixm->width / finfo->hdiv; -+ height = pixm->height / finfo->vdiv; -+ } -+ -+ switch (finfo->format) { -+ case V4L2_PIX_FMT_NV24: -+ case V4L2_PIX_FMT_NV16: -+ case V4L2_PIX_FMT_NV12: -+ case V4L2_PIX_FMT_BGR24: -+ bpp = finfo->bpp[i]; -+ break; -+ default: -+ v4l2_dbg(1, debug, v4l2_dev, -+ "fourcc: %#x is not supported\n", -+ finfo->format); -+ break; -+ } -+ -+ bpl = ALIGN(width * bpp, hw_align); -+ size = bpl * height; -+ imagesize += size; -+ -+ if (finfo->mem_planes > i) { -+ /* Set bpl and size for each mplane */ -+ plane_fmt = pixm->plane_fmt + i; -+ plane_fmt->bytesperline = bpl; -+ plane_fmt->sizeimage = size; -+ } -+ -+ v4l2_dbg(1, debug, v4l2_dev, -+ "C-Plane %i size: %d, Total imagesize: %d\n", -+ i, size, imagesize); -+ } -+ -+ /* Convert to non-MPLANE format as we want to unify non-MPLANE and MPLANE */ -+ if (finfo->mem_planes == 1) -+ pixm->plane_fmt[0].sizeimage = imagesize; -+ -+ if (!try) { -+ stream->out_finfo = finfo; -+ stream->pixm = *pixm; -+ v4l2_dbg(1, debug, v4l2_dev, -+ "%s: req(%d, %d), out(%d, %d), fmt:%#x\n", __func__, -+ pixm->width, pixm->height, stream->pixm.width, -+ stream->pixm.height, finfo->format); -+ } -+} -+ -+static int hdmirx_enum_fmt_vid_cap_mplane(struct file *file, void *priv, -+ struct v4l2_fmtdesc *f) -+{ -+ struct hdmirx_stream *stream = video_drvdata(file); -+ struct snps_hdmirx_dev *hdmirx_dev = stream->hdmirx_dev; -+ -+ if (f->index >= 1) -+ return -EINVAL; -+ -+ f->pixelformat = hdmirx_dev->cur_fmt_fourcc; -+ -+ return 0; -+} -+ -+static int hdmirx_s_fmt_vid_cap_mplane(struct file *file, -+ void *priv, struct v4l2_format *f) -+{ -+ struct hdmirx_stream *stream = video_drvdata(file); -+ struct snps_hdmirx_dev *hdmirx_dev = stream->hdmirx_dev; -+ struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; -+ -+ if (vb2_is_busy(&stream->buf_queue)) { -+ v4l2_err(v4l2_dev, "%s: queue busy\n", __func__); -+ return -EBUSY; -+ } -+ -+ hdmirx_set_fmt(stream, &f->fmt.pix_mp, false); -+ -+ return 0; -+} -+ -+static int hdmirx_g_fmt_vid_cap_mplane(struct file *file, void *fh, -+ struct v4l2_format *f) -+{ -+ struct hdmirx_stream *stream = video_drvdata(file); -+ struct snps_hdmirx_dev *hdmirx_dev = stream->hdmirx_dev; -+ struct v4l2_pix_format_mplane pixm = {}; -+ -+ pixm.pixelformat = hdmirx_dev->cur_fmt_fourcc; -+ hdmirx_set_fmt(stream, &pixm, true); -+ f->fmt.pix_mp = pixm; -+ -+ return 0; -+} -+ -+static int hdmirx_g_dv_timings(struct file *file, void *_fh, -+ struct v4l2_dv_timings *timings) -+{ -+ struct hdmirx_stream *stream = video_drvdata(file); -+ struct snps_hdmirx_dev *hdmirx_dev = stream->hdmirx_dev; -+ struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; -+ u32 dma_cfg1; -+ -+ *timings = hdmirx_dev->timings; -+ dma_cfg1 = hdmirx_readl(hdmirx_dev, DMA_CONFIG1); -+ v4l2_dbg(1, debug, v4l2_dev, "%s: pix_fmt: %s, DMA_CONFIG1:%#x\n", -+ __func__, pix_fmt_str[hdmirx_dev->pix_fmt], dma_cfg1); -+ -+ return 0; -+} -+ -+static int hdmirx_s_dv_timings(struct file *file, void *_fh, -+ struct v4l2_dv_timings *timings) -+{ -+ struct hdmirx_stream *stream = video_drvdata(file); -+ struct snps_hdmirx_dev *hdmirx_dev = stream->hdmirx_dev; -+ struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; -+ -+ if (!timings) -+ return -EINVAL; -+ -+ if (debug) -+ v4l2_print_dv_timings(hdmirx_dev->v4l2_dev.name, -+ "s_dv_timings: ", timings, false); -+ -+ if (!v4l2_valid_dv_timings(timings, &hdmirx_timings_cap, NULL, NULL)) { -+ v4l2_dbg(1, debug, v4l2_dev, -+ "%s: timings out of range\n", __func__); -+ return -ERANGE; -+ } -+ -+ /* Check if the timings are part of the CEA-861 timings. */ -+ v4l2_find_dv_timings_cap(timings, &hdmirx_timings_cap, 0, NULL, NULL); -+ -+ if (v4l2_match_dv_timings(&hdmirx_dev->timings, timings, 0, false)) { -+ v4l2_dbg(1, debug, v4l2_dev, "%s: no change\n", __func__); -+ return 0; -+ } -+ -+ /* -+ * Changing the timings implies a format change, which is not allowed -+ * while buffers for use with streaming have already been allocated. -+ */ -+ if (vb2_is_busy(&stream->buf_queue)) -+ return -EBUSY; -+ -+ hdmirx_dev->timings = *timings; -+ /* Update the internal format */ -+ hdmirx_set_fmt(stream, &stream->pixm, false); -+ -+ return 0; -+} -+ -+static int hdmirx_querycap(struct file *file, void *priv, -+ struct v4l2_capability *cap) -+{ -+ struct hdmirx_stream *stream = video_drvdata(file); -+ struct device *dev = stream->hdmirx_dev->dev; -+ -+ strscpy(cap->driver, dev->driver->name, sizeof(cap->driver)); -+ strscpy(cap->card, dev->driver->name, sizeof(cap->card)); -+ -+ return 0; -+} -+ -+static int hdmirx_queue_setup(struct vb2_queue *queue, -+ unsigned int *num_buffers, -+ unsigned int *num_planes, -+ unsigned int sizes[], -+ struct device *alloc_ctxs[]) -+{ -+ struct hdmirx_stream *stream = vb2_get_drv_priv(queue); -+ struct snps_hdmirx_dev *hdmirx_dev = stream->hdmirx_dev; -+ struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; -+ const struct v4l2_pix_format_mplane *pixm = NULL; -+ const struct v4l2_format_info *out_finfo; -+ u32 i, height; -+ -+ pixm = &stream->pixm; -+ out_finfo = stream->out_finfo; -+ -+ if (!out_finfo) { -+ v4l2_err(v4l2_dev, "%s: out_fmt not set\n", __func__); -+ return -EINVAL; -+ } -+ -+ if (*num_planes) { -+ if (*num_planes != pixm->num_planes) -+ return -EINVAL; -+ -+ for (i = 0; i < *num_planes; i++) -+ if (sizes[i] < pixm->plane_fmt[i].sizeimage) -+ return -EINVAL; -+ return 0; -+ } -+ -+ *num_planes = out_finfo->mem_planes; -+ height = pixm->height; -+ -+ for (i = 0; i < out_finfo->mem_planes; i++) -+ sizes[i] = pixm->plane_fmt[i].sizeimage; -+ -+ v4l2_dbg(1, debug, v4l2_dev, "%s: count %d, size %d\n", -+ v4l2_type_names[queue->type], *num_buffers, sizes[0]); -+ -+ return 0; -+} -+ -+/* -+ * The vb2_buffer are stored in hdmirx_buffer, in order to unify -+ * mplane buffer and none-mplane buffer. -+ */ -+static void hdmirx_buf_queue(struct vb2_buffer *vb) -+{ -+ const struct v4l2_pix_format_mplane *pixm; -+ const struct v4l2_format_info *out_finfo; -+ struct hdmirx_buffer *hdmirx_buf; -+ struct vb2_v4l2_buffer *vbuf; -+ struct hdmirx_stream *stream; -+ struct vb2_queue *queue; -+ unsigned long flags; -+ int i; -+ -+ vbuf = to_vb2_v4l2_buffer(vb); -+ hdmirx_buf = container_of(vbuf, struct hdmirx_buffer, vb); -+ queue = vb->vb2_queue; -+ stream = vb2_get_drv_priv(queue); -+ pixm = &stream->pixm; -+ out_finfo = stream->out_finfo; -+ -+ memset(hdmirx_buf->buff_addr, 0, sizeof(hdmirx_buf->buff_addr)); -+ -+ /* -+ * If mplanes > 1, every c-plane has its own m-plane, -+ * otherwise, multiple c-planes are in the same m-plane -+ */ -+ for (i = 0; i < out_finfo->mem_planes; i++) -+ hdmirx_buf->buff_addr[i] = vb2_dma_contig_plane_dma_addr(vb, i); -+ -+ if (out_finfo->mem_planes == 1) { -+ if (out_finfo->comp_planes == 1) { -+ hdmirx_buf->buff_addr[HDMIRX_PLANE_CBCR] = -+ hdmirx_buf->buff_addr[HDMIRX_PLANE_Y]; -+ } else { -+ for (i = 0; i < out_finfo->comp_planes - 1; i++) -+ hdmirx_buf->buff_addr[i + 1] = -+ hdmirx_buf->buff_addr[i] + -+ pixm->plane_fmt[i].bytesperline * -+ pixm->height; -+ } -+ } -+ -+ spin_lock_irqsave(&stream->vbq_lock, flags); -+ list_add_tail(&hdmirx_buf->queue, &stream->buf_head); -+ spin_unlock_irqrestore(&stream->vbq_lock, flags); -+} -+ -+static void return_all_buffers(struct hdmirx_stream *stream, -+ enum vb2_buffer_state state) -+{ -+ struct hdmirx_buffer *buf, *tmp; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&stream->vbq_lock, flags); -+ if (stream->curr_buf) -+ list_add_tail(&stream->curr_buf->queue, &stream->buf_head); -+ if (stream->next_buf && stream->next_buf != stream->curr_buf) -+ list_add_tail(&stream->next_buf->queue, &stream->buf_head); -+ stream->curr_buf = NULL; -+ stream->next_buf = NULL; -+ -+ list_for_each_entry_safe(buf, tmp, &stream->buf_head, queue) { -+ list_del(&buf->queue); -+ vb2_buffer_done(&buf->vb.vb2_buf, state); -+ } -+ spin_unlock_irqrestore(&stream->vbq_lock, flags); -+} -+ -+static void hdmirx_stop_streaming(struct vb2_queue *queue) -+{ -+ struct hdmirx_stream *stream = vb2_get_drv_priv(queue); -+ struct snps_hdmirx_dev *hdmirx_dev = stream->hdmirx_dev; -+ struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; -+ int ret; -+ -+ v4l2_dbg(1, debug, v4l2_dev, "stream start stopping\n"); -+ mutex_lock(&hdmirx_dev->stream_lock); -+ WRITE_ONCE(stream->stopping, true); -+ -+ /* wait last irq to return the buffer */ -+ ret = wait_event_timeout(stream->wq_stopped, !stream->stopping, -+ msecs_to_jiffies(500)); -+ if (!ret) -+ v4l2_dbg(1, debug, v4l2_dev, "%s: timeout waiting last irq\n", -+ __func__); -+ -+ hdmirx_update_bits(hdmirx_dev, DMA_CONFIG6, HDMIRX_DMA_EN, 0); -+ return_all_buffers(stream, VB2_BUF_STATE_ERROR); -+ mutex_unlock(&hdmirx_dev->stream_lock); -+ v4l2_dbg(1, debug, v4l2_dev, "stream stopping finished\n"); -+} -+ -+static int hdmirx_start_streaming(struct vb2_queue *queue, unsigned int count) -+{ -+ struct hdmirx_stream *stream = vb2_get_drv_priv(queue); -+ struct snps_hdmirx_dev *hdmirx_dev = stream->hdmirx_dev; -+ struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; -+ struct v4l2_dv_timings timings = hdmirx_dev->timings; -+ struct v4l2_bt_timings *bt = &timings.bt; -+ unsigned long lock_flags = 0; -+ int line_flag; -+ -+ mutex_lock(&hdmirx_dev->stream_lock); -+ stream->frame_idx = 0; -+ stream->line_flag_int_cnt = 0; -+ stream->curr_buf = NULL; -+ stream->next_buf = NULL; -+ stream->irq_stat = 0; -+ -+ WRITE_ONCE(stream->stopping, false); -+ -+ spin_lock_irqsave(&stream->vbq_lock, lock_flags); -+ if (!stream->curr_buf) { -+ if (!list_empty(&stream->buf_head)) { -+ stream->curr_buf = list_first_entry(&stream->buf_head, -+ struct hdmirx_buffer, -+ queue); -+ list_del(&stream->curr_buf->queue); -+ } else { -+ stream->curr_buf = NULL; -+ } -+ } -+ spin_unlock_irqrestore(&stream->vbq_lock, lock_flags); -+ -+ if (!stream->curr_buf) { -+ mutex_unlock(&hdmirx_dev->stream_lock); -+ return -ENOMEM; -+ } -+ -+ v4l2_dbg(2, debug, v4l2_dev, -+ "%s: start_stream cur_buf y_addr:%#x, uv_addr:%#x\n", -+ __func__, stream->curr_buf->buff_addr[HDMIRX_PLANE_Y], -+ stream->curr_buf->buff_addr[HDMIRX_PLANE_CBCR]); -+ hdmirx_writel(hdmirx_dev, DMA_CONFIG2, -+ stream->curr_buf->buff_addr[HDMIRX_PLANE_Y]); -+ hdmirx_writel(hdmirx_dev, DMA_CONFIG3, -+ stream->curr_buf->buff_addr[HDMIRX_PLANE_CBCR]); -+ -+ if (bt->height) { -+ if (bt->interlaced == V4L2_DV_INTERLACED) -+ line_flag = bt->height / 4; -+ else -+ line_flag = bt->height / 2; -+ hdmirx_update_bits(hdmirx_dev, DMA_CONFIG7, -+ LINE_FLAG_NUM_MASK, -+ LINE_FLAG_NUM(line_flag)); -+ } else { -+ v4l2_err(v4l2_dev, "height err: %d\n", bt->height); -+ } -+ -+ hdmirx_writel(hdmirx_dev, DMA_CONFIG5, 0xffffffff); -+ hdmirx_writel(hdmirx_dev, CED_DYN_CONTROL, 0x1); -+ hdmirx_update_bits(hdmirx_dev, DMA_CONFIG4, -+ LINE_FLAG_INT_EN | -+ HDMIRX_DMA_IDLE_INT | -+ HDMIRX_LOCK_DISABLE_INT | -+ LAST_FRAME_AXI_UNFINISH_INT_EN | -+ FIFO_OVERFLOW_INT_EN | -+ FIFO_UNDERFLOW_INT_EN | -+ HDMIRX_AXI_ERROR_INT_EN, -+ LINE_FLAG_INT_EN | -+ HDMIRX_DMA_IDLE_INT | -+ HDMIRX_LOCK_DISABLE_INT | -+ LAST_FRAME_AXI_UNFINISH_INT_EN | -+ FIFO_OVERFLOW_INT_EN | -+ FIFO_UNDERFLOW_INT_EN | -+ HDMIRX_AXI_ERROR_INT_EN); -+ hdmirx_update_bits(hdmirx_dev, DMA_CONFIG6, HDMIRX_DMA_EN, HDMIRX_DMA_EN); -+ v4l2_dbg(1, debug, v4l2_dev, "%s: enable dma", __func__); -+ mutex_unlock(&hdmirx_dev->stream_lock); -+ -+ return 0; -+} -+ -+/* vb2 queue */ -+static const struct vb2_ops hdmirx_vb2_ops = { -+ .queue_setup = hdmirx_queue_setup, -+ .buf_queue = hdmirx_buf_queue, -+ .wait_prepare = vb2_ops_wait_prepare, -+ .wait_finish = vb2_ops_wait_finish, -+ .stop_streaming = hdmirx_stop_streaming, -+ .start_streaming = hdmirx_start_streaming, -+}; -+ -+static int hdmirx_init_vb2_queue(struct vb2_queue *q, -+ struct hdmirx_stream *stream, -+ enum v4l2_buf_type buf_type) -+{ -+ struct snps_hdmirx_dev *hdmirx_dev = stream->hdmirx_dev; -+ -+ q->type = buf_type; -+ q->io_modes = VB2_MMAP | VB2_DMABUF; -+ q->drv_priv = stream; -+ q->ops = &hdmirx_vb2_ops; -+ q->mem_ops = &vb2_dma_contig_memops; -+ q->buf_struct_size = sizeof(struct hdmirx_buffer); -+ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; -+ q->lock = &stream->vlock; -+ q->dev = hdmirx_dev->dev; -+ q->min_queued_buffers = 1; -+ -+ return vb2_queue_init(q); -+} -+ -+/* video device */ -+static const struct v4l2_ioctl_ops hdmirx_v4l2_ioctl_ops = { -+ .vidioc_querycap = hdmirx_querycap, -+ .vidioc_try_fmt_vid_cap_mplane = hdmirx_g_fmt_vid_cap_mplane, -+ .vidioc_s_fmt_vid_cap_mplane = hdmirx_s_fmt_vid_cap_mplane, -+ .vidioc_g_fmt_vid_cap_mplane = hdmirx_g_fmt_vid_cap_mplane, -+ .vidioc_enum_fmt_vid_cap = hdmirx_enum_fmt_vid_cap_mplane, -+ -+ .vidioc_s_dv_timings = hdmirx_s_dv_timings, -+ .vidioc_g_dv_timings = hdmirx_g_dv_timings, -+ .vidioc_enum_dv_timings = hdmirx_enum_dv_timings, -+ .vidioc_query_dv_timings = hdmirx_query_dv_timings, -+ .vidioc_dv_timings_cap = hdmirx_dv_timings_cap, -+ .vidioc_enum_input = hdmirx_enum_input, -+ .vidioc_g_input = hdmirx_get_input, -+ .vidioc_s_input = hdmirx_set_input, -+ .vidioc_g_edid = hdmirx_get_edid, -+ .vidioc_s_edid = hdmirx_set_edid, -+ .vidioc_g_parm = hdmirx_g_parm, -+ -+ .vidioc_reqbufs = vb2_ioctl_reqbufs, -+ .vidioc_querybuf = vb2_ioctl_querybuf, -+ .vidioc_create_bufs = vb2_ioctl_create_bufs, -+ .vidioc_qbuf = vb2_ioctl_qbuf, -+ .vidioc_expbuf = vb2_ioctl_expbuf, -+ .vidioc_dqbuf = vb2_ioctl_dqbuf, -+ .vidioc_prepare_buf = vb2_ioctl_prepare_buf, -+ .vidioc_streamon = vb2_ioctl_streamon, -+ .vidioc_streamoff = vb2_ioctl_streamoff, -+ -+ .vidioc_log_status = v4l2_ctrl_log_status, -+ .vidioc_subscribe_event = hdmirx_subscribe_event, -+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe, -+}; -+ -+static const struct v4l2_file_operations hdmirx_fops = { -+ .owner = THIS_MODULE, -+ .open = v4l2_fh_open, -+ .release = vb2_fop_release, -+ .unlocked_ioctl = video_ioctl2, -+ .poll = vb2_fop_poll, -+ .mmap = vb2_fop_mmap, -+}; -+ -+static int hdmirx_register_stream_vdev(struct hdmirx_stream *stream) -+{ -+ struct snps_hdmirx_dev *hdmirx_dev = stream->hdmirx_dev; -+ struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; -+ struct video_device *vdev = &stream->vdev; -+ int ret = 0; -+ -+ strscpy(vdev->name, "stream_hdmirx", sizeof(vdev->name)); -+ INIT_LIST_HEAD(&stream->buf_head); -+ spin_lock_init(&stream->vbq_lock); -+ mutex_init(&stream->vlock); -+ init_waitqueue_head(&stream->wq_stopped); -+ stream->curr_buf = NULL; -+ stream->next_buf = NULL; -+ -+ vdev->ioctl_ops = &hdmirx_v4l2_ioctl_ops; -+ vdev->release = video_device_release_empty; -+ vdev->fops = &hdmirx_fops; -+ vdev->minor = -1; -+ vdev->v4l2_dev = v4l2_dev; -+ vdev->lock = &stream->vlock; -+ vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE | -+ V4L2_CAP_STREAMING; -+ video_set_drvdata(vdev, stream); -+ vdev->vfl_dir = VFL_DIR_RX; -+ -+ hdmirx_init_vb2_queue(&stream->buf_queue, stream, -+ V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); -+ vdev->queue = &stream->buf_queue; -+ -+ ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); -+ if (ret < 0) { -+ v4l2_err(v4l2_dev, "video_register_device failed: %d\n", ret); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static void process_signal_change(struct snps_hdmirx_dev *hdmirx_dev) -+{ -+ hdmirx_update_bits(hdmirx_dev, DMA_CONFIG6, HDMIRX_DMA_EN, 0); -+ hdmirx_update_bits(hdmirx_dev, DMA_CONFIG4, -+ LINE_FLAG_INT_EN | -+ HDMIRX_DMA_IDLE_INT | -+ HDMIRX_LOCK_DISABLE_INT | -+ LAST_FRAME_AXI_UNFINISH_INT_EN | -+ FIFO_OVERFLOW_INT_EN | -+ FIFO_UNDERFLOW_INT_EN | -+ HDMIRX_AXI_ERROR_INT_EN, 0); -+ hdmirx_reset_dma(hdmirx_dev); -+ queue_delayed_work(system_unbound_wq, -+ &hdmirx_dev->delayed_work_res_change, -+ msecs_to_jiffies(50)); -+} -+ -+static void avpunit_0_int_handler(struct snps_hdmirx_dev *hdmirx_dev, -+ int status, bool *handled) -+{ -+ struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; -+ -+ if (status & (CED_DYN_CNT_CH2_IRQ | -+ CED_DYN_CNT_CH1_IRQ | -+ CED_DYN_CNT_CH0_IRQ)) { -+ process_signal_change(hdmirx_dev); -+ v4l2_dbg(2, debug, v4l2_dev, "%s: avp0_st:%#x\n", -+ __func__, status); -+ *handled = true; -+ } -+ -+ hdmirx_clear_interrupt(hdmirx_dev, AVPUNIT_0_INT_CLEAR, 0xffffffff); -+ hdmirx_writel(hdmirx_dev, AVPUNIT_0_INT_FORCE, 0x0); -+} -+ -+static void avpunit_1_int_handler(struct snps_hdmirx_dev *hdmirx_dev, -+ int status, bool *handled) -+{ -+ struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; -+ -+ if (status & DEFRAMER_VSYNC_THR_REACHED_IRQ) { -+ v4l2_dbg(2, debug, v4l2_dev, -+ "Vertical Sync threshold reached interrupt %#x", status); -+ hdmirx_update_bits(hdmirx_dev, AVPUNIT_1_INT_MASK_N, -+ DEFRAMER_VSYNC_THR_REACHED_MASK_N, 0); -+ *handled = true; -+ } -+} -+ -+static void mainunit_0_int_handler(struct snps_hdmirx_dev *hdmirx_dev, -+ int status, bool *handled) -+{ -+ struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; -+ -+ v4l2_dbg(2, debug, v4l2_dev, "mu0_st:%#x\n", status); -+ if (status & TIMER_BASE_LOCKED_IRQ) { -+ hdmirx_update_bits(hdmirx_dev, MAINUNIT_0_INT_MASK_N, -+ TIMER_BASE_LOCKED_IRQ, 0); -+ complete(&hdmirx_dev->timer_base_lock); -+ *handled = true; -+ } -+ -+ if (status & TMDSQPCLK_OFF_CHG) { -+ process_signal_change(hdmirx_dev); -+ v4l2_dbg(2, debug, v4l2_dev, "%s: TMDSQPCLK_OFF_CHG\n", __func__); -+ *handled = true; -+ } -+ -+ if (status & TMDSQPCLK_LOCKED_CHG) { -+ process_signal_change(hdmirx_dev); -+ v4l2_dbg(2, debug, v4l2_dev, "%s: TMDSQPCLK_LOCKED_CHG\n", __func__); -+ *handled = true; -+ } -+ -+ hdmirx_clear_interrupt(hdmirx_dev, MAINUNIT_0_INT_CLEAR, 0xffffffff); -+ hdmirx_writel(hdmirx_dev, MAINUNIT_0_INT_FORCE, 0x0); -+} -+ -+static void mainunit_2_int_handler(struct snps_hdmirx_dev *hdmirx_dev, -+ int status, bool *handled) -+{ -+ struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; -+ -+ v4l2_dbg(2, debug, v4l2_dev, "mu2_st:%#x\n", status); -+ if (status & PHYCREG_CR_WRITE_DONE) { -+ hdmirx_update_bits(hdmirx_dev, MAINUNIT_2_INT_MASK_N, -+ PHYCREG_CR_WRITE_DONE, 0); -+ complete(&hdmirx_dev->cr_write_done); -+ *handled = true; -+ } -+ -+ if (status & TMDSVALID_STABLE_CHG) { -+ process_signal_change(hdmirx_dev); -+ v4l2_dbg(2, debug, v4l2_dev, "%s: TMDSVALID_STABLE_CHG\n", __func__); -+ *handled = true; -+ } -+ -+ hdmirx_clear_interrupt(hdmirx_dev, MAINUNIT_2_INT_CLEAR, 0xffffffff); -+ hdmirx_writel(hdmirx_dev, MAINUNIT_2_INT_FORCE, 0x0); -+} -+ -+static void pkt_2_int_handler(struct snps_hdmirx_dev *hdmirx_dev, -+ int status, bool *handled) -+{ -+ struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; -+ -+ v4l2_dbg(2, debug, v4l2_dev, "%s: pk2_st:%#x\n", __func__, status); -+ if (status & PKTDEC_AVIIF_RCV_IRQ) { -+ hdmirx_update_bits(hdmirx_dev, PKT_2_INT_MASK_N, -+ PKTDEC_AVIIF_RCV_IRQ, 0); -+ complete(&hdmirx_dev->avi_pkt_rcv); -+ v4l2_dbg(2, debug, v4l2_dev, "%s: AVIIF_RCV_IRQ\n", __func__); -+ *handled = true; -+ } -+ -+ hdmirx_clear_interrupt(hdmirx_dev, PKT_2_INT_CLEAR, 0xffffffff); -+} -+ -+static void scdc_int_handler(struct snps_hdmirx_dev *hdmirx_dev, -+ int status, bool *handled) -+{ -+ struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; -+ -+ v4l2_dbg(2, debug, v4l2_dev, "%s: scdc_st:%#x\n", __func__, status); -+ if (status & SCDCTMDSCCFG_CHG) { -+ hdmirx_tmds_clk_ratio_config(hdmirx_dev); -+ *handled = true; -+ } -+ -+ hdmirx_clear_interrupt(hdmirx_dev, SCDC_INT_CLEAR, 0xffffffff); -+} -+ -+static irqreturn_t hdmirx_hdmi_irq_handler(int irq, void *dev_id) -+{ -+ struct snps_hdmirx_dev *hdmirx_dev = dev_id; -+ struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; -+ u32 mu0_st, mu2_st, pk2_st, scdc_st, avp1_st, avp0_st; -+ u32 mu0_mask, mu2_mask, pk2_mask, scdc_mask, avp1_msk, avp0_msk; -+ bool handled = false; -+ -+ mu0_mask = hdmirx_readl(hdmirx_dev, MAINUNIT_0_INT_MASK_N); -+ mu2_mask = hdmirx_readl(hdmirx_dev, MAINUNIT_2_INT_MASK_N); -+ pk2_mask = hdmirx_readl(hdmirx_dev, PKT_2_INT_MASK_N); -+ scdc_mask = hdmirx_readl(hdmirx_dev, SCDC_INT_MASK_N); -+ mu0_st = hdmirx_readl(hdmirx_dev, MAINUNIT_0_INT_STATUS); -+ mu2_st = hdmirx_readl(hdmirx_dev, MAINUNIT_2_INT_STATUS); -+ pk2_st = hdmirx_readl(hdmirx_dev, PKT_2_INT_STATUS); -+ scdc_st = hdmirx_readl(hdmirx_dev, SCDC_INT_STATUS); -+ avp0_st = hdmirx_readl(hdmirx_dev, AVPUNIT_0_INT_STATUS); -+ avp1_st = hdmirx_readl(hdmirx_dev, AVPUNIT_1_INT_STATUS); -+ avp0_msk = hdmirx_readl(hdmirx_dev, AVPUNIT_0_INT_MASK_N); -+ avp1_msk = hdmirx_readl(hdmirx_dev, AVPUNIT_1_INT_MASK_N); -+ mu0_st &= mu0_mask; -+ mu2_st &= mu2_mask; -+ pk2_st &= pk2_mask; -+ avp1_st &= avp1_msk; -+ avp0_st &= avp0_msk; -+ scdc_st &= scdc_mask; -+ -+ if (avp0_st) -+ avpunit_0_int_handler(hdmirx_dev, avp0_st, &handled); -+ if (avp1_st) -+ avpunit_1_int_handler(hdmirx_dev, avp1_st, &handled); -+ if (mu0_st) -+ mainunit_0_int_handler(hdmirx_dev, mu0_st, &handled); -+ if (mu2_st) -+ mainunit_2_int_handler(hdmirx_dev, mu2_st, &handled); -+ if (pk2_st) -+ pkt_2_int_handler(hdmirx_dev, pk2_st, &handled); -+ if (scdc_st) -+ scdc_int_handler(hdmirx_dev, scdc_st, &handled); -+ -+ if (!handled) { -+ v4l2_dbg(2, debug, v4l2_dev, "%s: hdmi irq not handled", __func__); -+ v4l2_dbg(2, debug, v4l2_dev, -+ "avp0:%#x, avp1:%#x, mu0:%#x, mu2:%#x, pk2:%#x, scdc:%#x\n", -+ avp0_st, avp1_st, mu0_st, mu2_st, pk2_st, scdc_st); -+ } -+ -+ v4l2_dbg(2, debug, v4l2_dev, "%s: en_fiq", __func__); -+ -+ return handled ? IRQ_HANDLED : IRQ_NONE; -+} -+ -+static void hdmirx_vb_done(struct hdmirx_stream *stream, -+ struct vb2_v4l2_buffer *vb_done) -+{ -+ const struct v4l2_format_info *finfo = stream->out_finfo; -+ u32 i; -+ -+ /* Dequeue a filled buffer */ -+ for (i = 0; i < finfo->mem_planes; i++) { -+ vb2_set_plane_payload(&vb_done->vb2_buf, i, -+ stream->pixm.plane_fmt[i].sizeimage); -+ } -+ -+ vb_done->vb2_buf.timestamp = ktime_get_ns(); -+ vb2_buffer_done(&vb_done->vb2_buf, VB2_BUF_STATE_DONE); -+} -+ -+static void dma_idle_int_handler(struct snps_hdmirx_dev *hdmirx_dev, -+ bool *handled) -+{ -+ struct hdmirx_stream *stream = &hdmirx_dev->stream; -+ struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; -+ struct v4l2_dv_timings timings = hdmirx_dev->timings; -+ struct v4l2_bt_timings *bt = &timings.bt; -+ struct vb2_v4l2_buffer *vb_done = NULL; -+ -+ if (!(stream->irq_stat) && !(stream->irq_stat & LINE_FLAG_INT_EN)) -+ v4l2_dbg(1, debug, v4l2_dev, -+ "%s: last time have no line_flag_irq\n", __func__); -+ -+ if (stream->line_flag_int_cnt <= FILTER_FRAME_CNT) -+ goto DMA_IDLE_OUT; -+ -+ if (bt->interlaced != V4L2_DV_INTERLACED || -+ !(stream->line_flag_int_cnt % 2)) { -+ if (stream->next_buf) { -+ if (stream->curr_buf) -+ vb_done = &stream->curr_buf->vb; -+ -+ if (vb_done) { -+ vb_done->vb2_buf.timestamp = ktime_get_ns(); -+ vb_done->sequence = stream->frame_idx; -+ -+ if (bt->interlaced) -+ vb_done->field = V4L2_FIELD_INTERLACED_TB; -+ else -+ vb_done->field = V4L2_FIELD_NONE; -+ -+ hdmirx_vb_done(stream, vb_done); -+ stream->frame_idx++; -+ if (stream->frame_idx == 30) -+ v4l2_dbg(1, debug, v4l2_dev, -+ "rcv frames\n"); -+ } -+ -+ stream->curr_buf = NULL; -+ if (stream->next_buf) { -+ stream->curr_buf = stream->next_buf; -+ stream->next_buf = NULL; -+ } -+ } else { -+ v4l2_dbg(3, debug, v4l2_dev, -+ "%s: next_buf NULL, skip vb_done\n", __func__); -+ } -+ } -+ -+DMA_IDLE_OUT: -+ *handled = true; -+} -+ -+static void line_flag_int_handler(struct snps_hdmirx_dev *hdmirx_dev, -+ bool *handled) -+{ -+ struct hdmirx_stream *stream = &hdmirx_dev->stream; -+ struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; -+ struct v4l2_dv_timings timings = hdmirx_dev->timings; -+ struct v4l2_bt_timings *bt = &timings.bt; -+ u32 dma_cfg6; -+ -+ stream->line_flag_int_cnt++; -+ if (!(stream->irq_stat) && !(stream->irq_stat & HDMIRX_DMA_IDLE_INT)) -+ v4l2_dbg(1, debug, v4l2_dev, -+ "%s: last have no dma_idle_irq\n", __func__); -+ dma_cfg6 = hdmirx_readl(hdmirx_dev, DMA_CONFIG6); -+ if (!(dma_cfg6 & HDMIRX_DMA_EN)) { -+ v4l2_dbg(2, debug, v4l2_dev, "%s: dma not on\n", __func__); -+ goto LINE_FLAG_OUT; -+ } -+ -+ if (stream->line_flag_int_cnt <= FILTER_FRAME_CNT) -+ goto LINE_FLAG_OUT; -+ -+ if (bt->interlaced != V4L2_DV_INTERLACED || -+ !(stream->line_flag_int_cnt % 2)) { -+ if (!stream->next_buf) { -+ spin_lock(&stream->vbq_lock); -+ if (!list_empty(&stream->buf_head)) { -+ stream->next_buf = list_first_entry(&stream->buf_head, -+ struct hdmirx_buffer, -+ queue); -+ list_del(&stream->next_buf->queue); -+ } else { -+ stream->next_buf = NULL; -+ } -+ spin_unlock(&stream->vbq_lock); -+ -+ if (stream->next_buf) { -+ hdmirx_writel(hdmirx_dev, DMA_CONFIG2, -+ stream->next_buf->buff_addr[HDMIRX_PLANE_Y]); -+ hdmirx_writel(hdmirx_dev, DMA_CONFIG3, -+ stream->next_buf->buff_addr[HDMIRX_PLANE_CBCR]); -+ } else { -+ v4l2_dbg(3, debug, v4l2_dev, -+ "%s: no buffer is available\n", __func__); -+ } -+ } -+ } else { -+ v4l2_dbg(3, debug, v4l2_dev, "%s: interlace:%d, line_flag_int_cnt:%d\n", -+ __func__, bt->interlaced, stream->line_flag_int_cnt); -+ } -+ -+LINE_FLAG_OUT: -+ *handled = true; -+} -+ -+static irqreturn_t hdmirx_dma_irq_handler(int irq, void *dev_id) -+{ -+ struct snps_hdmirx_dev *hdmirx_dev = dev_id; -+ struct hdmirx_stream *stream = &hdmirx_dev->stream; -+ struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; -+ u32 dma_stat1, dma_stat13; -+ bool handled = false; -+ -+ dma_stat1 = hdmirx_readl(hdmirx_dev, DMA_STATUS1); -+ dma_stat13 = hdmirx_readl(hdmirx_dev, DMA_STATUS13); -+ v4l2_dbg(3, debug, v4l2_dev, "dma_irq st1:%#x, st13:%d\n", -+ dma_stat1, dma_stat13); -+ -+ if (READ_ONCE(stream->stopping)) { -+ v4l2_dbg(1, debug, v4l2_dev, "%s: stop stream\n", __func__); -+ hdmirx_writel(hdmirx_dev, DMA_CONFIG5, 0xffffffff); -+ hdmirx_update_bits(hdmirx_dev, DMA_CONFIG4, -+ LINE_FLAG_INT_EN | -+ HDMIRX_DMA_IDLE_INT | -+ HDMIRX_LOCK_DISABLE_INT | -+ LAST_FRAME_AXI_UNFINISH_INT_EN | -+ FIFO_OVERFLOW_INT_EN | -+ FIFO_UNDERFLOW_INT_EN | -+ HDMIRX_AXI_ERROR_INT_EN, 0); -+ WRITE_ONCE(stream->stopping, false); -+ wake_up(&stream->wq_stopped); -+ return IRQ_HANDLED; -+ } -+ -+ if (dma_stat1 & HDMIRX_DMA_IDLE_INT) -+ dma_idle_int_handler(hdmirx_dev, &handled); -+ -+ if (dma_stat1 & LINE_FLAG_INT_EN) -+ line_flag_int_handler(hdmirx_dev, &handled); -+ -+ if (!handled) -+ v4l2_dbg(3, debug, v4l2_dev, -+ "%s: dma irq not handled, dma_stat1:%#x\n", -+ __func__, dma_stat1); -+ -+ stream->irq_stat = dma_stat1; -+ hdmirx_writel(hdmirx_dev, DMA_CONFIG5, 0xffffffff); -+ -+ return IRQ_HANDLED; -+} -+ -+static int hdmirx_wait_signal_lock(struct snps_hdmirx_dev *hdmirx_dev) -+{ -+ struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; -+ u32 mu_status, scdc_status, dma_st10, cmu_st; -+ u32 i; -+ -+ for (i = 0; i < 300; i++) { -+ mu_status = hdmirx_readl(hdmirx_dev, MAINUNIT_STATUS); -+ scdc_status = hdmirx_readl(hdmirx_dev, SCDC_REGBANK_STATUS3); -+ dma_st10 = hdmirx_readl(hdmirx_dev, DMA_STATUS10); -+ cmu_st = hdmirx_readl(hdmirx_dev, CMU_STATUS); -+ -+ if ((mu_status & TMDSVALID_STABLE_ST) && -+ (dma_st10 & HDMIRX_LOCK) && -+ (cmu_st & TMDSQPCLK_LOCKED_ST)) -+ break; -+ -+ if (!tx_5v_power_present(hdmirx_dev)) { -+ v4l2_dbg(1, debug, v4l2_dev, -+ "%s: HDMI pull out, return\n", __func__); -+ return -1; -+ } -+ -+ hdmirx_tmds_clk_ratio_config(hdmirx_dev); -+ } -+ -+ if (i == 300) { -+ v4l2_err(v4l2_dev, "%s: signal not lock, tmds_clk_ratio:%d\n", -+ __func__, hdmirx_dev->tmds_clk_ratio); -+ v4l2_err(v4l2_dev, "%s: mu_st:%#x, scdc_st:%#x, dma_st10:%#x\n", -+ __func__, mu_status, scdc_status, dma_st10); -+ return -1; -+ } -+ -+ v4l2_dbg(1, debug, v4l2_dev, "%s: signal lock ok, i:%d\n", __func__, i); -+ hdmirx_writel(hdmirx_dev, GLOBAL_SWRESET_REQUEST, DATAPATH_SWRESETREQ); -+ -+ reinit_completion(&hdmirx_dev->avi_pkt_rcv); -+ hdmirx_clear_interrupt(hdmirx_dev, PKT_2_INT_CLEAR, 0xffffffff); -+ hdmirx_update_bits(hdmirx_dev, PKT_2_INT_MASK_N, -+ PKTDEC_AVIIF_RCV_IRQ, PKTDEC_AVIIF_RCV_IRQ); -+ -+ if (!wait_for_completion_timeout(&hdmirx_dev->avi_pkt_rcv, -+ msecs_to_jiffies(300))) { -+ v4l2_err(v4l2_dev, "%s wait avi_pkt_rcv failed\n", __func__); -+ hdmirx_update_bits(hdmirx_dev, PKT_2_INT_MASK_N, -+ PKTDEC_AVIIF_RCV_IRQ, 0); -+ } -+ -+ msleep(50); -+ hdmirx_format_change(hdmirx_dev); -+ -+ return 0; -+} -+ -+static void hdmirx_plugin(struct snps_hdmirx_dev *hdmirx_dev) -+{ -+ hdmirx_submodule_init(hdmirx_dev); -+ hdmirx_update_bits(hdmirx_dev, SCDC_CONFIG, POWERPROVIDED, -+ POWERPROVIDED); -+ hdmirx_hpd_ctrl(hdmirx_dev, true); -+ hdmirx_phy_config(hdmirx_dev); -+ hdmirx_interrupts_setup(hdmirx_dev, true); -+} -+ -+static void hdmirx_delayed_work_hotplug(struct work_struct *work) -+{ -+ struct snps_hdmirx_dev *hdmirx_dev; -+ bool plugin; -+ -+ hdmirx_dev = container_of(work, struct snps_hdmirx_dev, -+ delayed_work_hotplug.work); -+ -+ mutex_lock(&hdmirx_dev->work_lock); -+ plugin = tx_5v_power_present(hdmirx_dev); -+ v4l2_ctrl_s_ctrl(hdmirx_dev->detect_tx_5v_ctrl, plugin); -+ v4l2_dbg(1, debug, &hdmirx_dev->v4l2_dev, "%s: plugin:%d\n", -+ __func__, plugin); -+ -+ if (plugin) -+ hdmirx_plugin(hdmirx_dev); -+ else -+ hdmirx_plugout(hdmirx_dev); -+ -+ mutex_unlock(&hdmirx_dev->work_lock); -+} -+ -+static void hdmirx_delayed_work_res_change(struct work_struct *work) -+{ -+ struct snps_hdmirx_dev *hdmirx_dev; -+ bool plugin; -+ -+ hdmirx_dev = container_of(work, struct snps_hdmirx_dev, -+ delayed_work_res_change.work); -+ -+ mutex_lock(&hdmirx_dev->work_lock); -+ plugin = tx_5v_power_present(hdmirx_dev); -+ v4l2_dbg(1, debug, &hdmirx_dev->v4l2_dev, "%s: plugin:%d\n", -+ __func__, plugin); -+ if (plugin) { -+ hdmirx_interrupts_setup(hdmirx_dev, false); -+ hdmirx_submodule_init(hdmirx_dev); -+ hdmirx_update_bits(hdmirx_dev, SCDC_CONFIG, POWERPROVIDED, -+ POWERPROVIDED); -+ hdmirx_hpd_ctrl(hdmirx_dev, true); -+ hdmirx_phy_config(hdmirx_dev); -+ -+ if (hdmirx_wait_signal_lock(hdmirx_dev)) { -+ hdmirx_plugout(hdmirx_dev); -+ queue_delayed_work(system_unbound_wq, -+ &hdmirx_dev->delayed_work_hotplug, -+ msecs_to_jiffies(200)); -+ } else { -+ hdmirx_dma_config(hdmirx_dev); -+ hdmirx_interrupts_setup(hdmirx_dev, true); -+ } -+ } -+ mutex_unlock(&hdmirx_dev->work_lock); -+} -+ -+static irqreturn_t hdmirx_5v_det_irq_handler(int irq, void *dev_id) -+{ -+ struct snps_hdmirx_dev *hdmirx_dev = dev_id; -+ u32 val; -+ -+ val = gpiod_get_value(hdmirx_dev->detect_5v_gpio); -+ v4l2_dbg(3, debug, &hdmirx_dev->v4l2_dev, "%s: 5v:%d\n", __func__, val); -+ -+ queue_delayed_work(system_unbound_wq, -+ &hdmirx_dev->delayed_work_hotplug, -+ msecs_to_jiffies(10)); -+ -+ return IRQ_HANDLED; -+} -+ -+static const struct hdmirx_cec_ops hdmirx_cec_ops = { -+ .write = hdmirx_writel, -+ .read = hdmirx_readl, -+}; -+ -+static int hdmirx_parse_dt(struct snps_hdmirx_dev *hdmirx_dev) -+{ -+ struct device *dev = hdmirx_dev->dev; -+ int ret; -+ -+ hdmirx_dev->num_clks = devm_clk_bulk_get_all(dev, &hdmirx_dev->clks); -+ if (hdmirx_dev->num_clks < 1) -+ return -ENODEV; -+ -+ hdmirx_dev->resets[HDMIRX_RST_A].id = "axi"; -+ hdmirx_dev->resets[HDMIRX_RST_P].id = "apb"; -+ hdmirx_dev->resets[HDMIRX_RST_REF].id = "ref"; -+ hdmirx_dev->resets[HDMIRX_RST_BIU].id = "biu"; -+ -+ ret = devm_reset_control_bulk_get_exclusive(dev, HDMIRX_NUM_RST, -+ hdmirx_dev->resets); -+ if (ret < 0) { -+ dev_err(dev, "failed to get reset controls\n"); -+ return ret; -+ } -+ -+ hdmirx_dev->detect_5v_gpio = -+ devm_gpiod_get_optional(dev, "hpd", GPIOD_IN); -+ -+ if (IS_ERR(hdmirx_dev->detect_5v_gpio)) { -+ dev_err(dev, "failed to get hdmirx hot plug detection gpio\n"); -+ return PTR_ERR(hdmirx_dev->detect_5v_gpio); -+ } -+ -+ hdmirx_dev->grf = syscon_regmap_lookup_by_phandle(dev->of_node, -+ "rockchip,grf"); -+ if (IS_ERR(hdmirx_dev->grf)) { -+ dev_err(dev, "failed to get rockchip,grf\n"); -+ return PTR_ERR(hdmirx_dev->grf); -+ } -+ -+ hdmirx_dev->vo1_grf = syscon_regmap_lookup_by_phandle(dev->of_node, -+ "rockchip,vo1-grf"); -+ if (IS_ERR(hdmirx_dev->vo1_grf)) { -+ dev_err(dev, "failed to get rockchip,vo1-grf\n"); -+ return PTR_ERR(hdmirx_dev->vo1_grf); -+ } -+ -+ if (!device_property_read_bool(dev, "hpd-is-active-low")) -+ hdmirx_dev->hpd_trigger_level_high = true; -+ -+ ret = of_reserved_mem_device_init(dev); -+ if (ret) -+ dev_warn(dev, "No reserved memory for HDMIRX, use default CMA\n"); -+ -+ return 0; -+} -+ -+static void hdmirx_disable_all_interrupts(struct snps_hdmirx_dev *hdmirx_dev) -+{ -+ hdmirx_writel(hdmirx_dev, MAINUNIT_0_INT_MASK_N, 0); -+ hdmirx_writel(hdmirx_dev, MAINUNIT_1_INT_MASK_N, 0); -+ hdmirx_writel(hdmirx_dev, MAINUNIT_2_INT_MASK_N, 0); -+ hdmirx_writel(hdmirx_dev, AVPUNIT_0_INT_MASK_N, 0); -+ hdmirx_writel(hdmirx_dev, AVPUNIT_1_INT_MASK_N, 0); -+ hdmirx_writel(hdmirx_dev, PKT_0_INT_MASK_N, 0); -+ hdmirx_writel(hdmirx_dev, PKT_1_INT_MASK_N, 0); -+ hdmirx_writel(hdmirx_dev, PKT_2_INT_MASK_N, 0); -+ hdmirx_writel(hdmirx_dev, SCDC_INT_MASK_N, 0); -+ hdmirx_writel(hdmirx_dev, CEC_INT_MASK_N, 0); -+ -+ hdmirx_clear_interrupt(hdmirx_dev, MAINUNIT_0_INT_CLEAR, 0xffffffff); -+ hdmirx_clear_interrupt(hdmirx_dev, MAINUNIT_1_INT_CLEAR, 0xffffffff); -+ hdmirx_clear_interrupt(hdmirx_dev, MAINUNIT_2_INT_CLEAR, 0xffffffff); -+ hdmirx_clear_interrupt(hdmirx_dev, AVPUNIT_0_INT_CLEAR, 0xffffffff); -+ hdmirx_clear_interrupt(hdmirx_dev, AVPUNIT_1_INT_CLEAR, 0xffffffff); -+ hdmirx_clear_interrupt(hdmirx_dev, PKT_0_INT_CLEAR, 0xffffffff); -+ hdmirx_clear_interrupt(hdmirx_dev, PKT_1_INT_CLEAR, 0xffffffff); -+ hdmirx_clear_interrupt(hdmirx_dev, PKT_2_INT_CLEAR, 0xffffffff); -+ hdmirx_clear_interrupt(hdmirx_dev, SCDC_INT_CLEAR, 0xffffffff); -+ hdmirx_clear_interrupt(hdmirx_dev, HDCP_INT_CLEAR, 0xffffffff); -+ hdmirx_clear_interrupt(hdmirx_dev, HDCP_1_INT_CLEAR, 0xffffffff); -+ hdmirx_clear_interrupt(hdmirx_dev, CEC_INT_CLEAR, 0xffffffff); -+} -+ -+static int hdmirx_init(struct snps_hdmirx_dev *hdmirx_dev) -+{ -+ hdmirx_update_bits(hdmirx_dev, PHY_CONFIG, PHY_RESET | PHY_PDDQ, 0); -+ -+ regmap_write(hdmirx_dev->vo1_grf, VO1_GRF_VO1_CON2, -+ (HDMIRX_SDAIN_MSK | HDMIRX_SCLIN_MSK) | -+ ((HDMIRX_SDAIN_MSK | HDMIRX_SCLIN_MSK) << 16)); -+ /* -+ * Some interrupts are enabled by default, so we disable -+ * all interrupts and clear interrupts status first. -+ */ -+ hdmirx_disable_all_interrupts(hdmirx_dev); -+ -+ return 0; -+} -+ -+/* hdmi-4k-300mhz EDID produced by v4l2-ctl tool */ -+static u8 edid_default[] = { -+ 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, -+ 0x31, 0xd8, 0x34, 0x12, 0x00, 0x00, 0x00, 0x00, -+ 0x22, 0x1a, 0x01, 0x03, 0x80, 0x60, 0x36, 0x78, -+ 0x0f, 0xee, 0x91, 0xa3, 0x54, 0x4c, 0x99, 0x26, -+ 0x0f, 0x50, 0x54, 0x2f, 0xcf, 0x00, 0x31, 0x59, -+ 0x45, 0x59, 0x81, 0x80, 0x81, 0x40, 0x90, 0x40, -+ 0x95, 0x00, 0xa9, 0x40, 0xb3, 0x00, 0x04, 0x74, -+ 0x00, 0x30, 0xf2, 0x70, 0x5a, 0x80, 0xb0, 0x58, -+ 0x8a, 0x00, 0xc0, 0x1c, 0x32, 0x00, 0x00, 0x1e, -+ 0x00, 0x00, 0x00, 0xfd, 0x00, 0x18, 0x55, 0x18, -+ 0x87, 0x1e, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, -+ 0x20, 0x20, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x68, -+ 0x64, 0x6d, 0x69, 0x2d, 0x34, 0x6b, 0x2d, 0x33, -+ 0x30, 0x30, 0x0a, 0x20, 0x00, 0x00, 0x00, 0x10, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc5, -+ -+ 0x02, 0x03, 0x40, 0xf1, 0x4f, 0x5f, 0x5e, 0x5d, -+ 0x10, 0x1f, 0x04, 0x13, 0x22, 0x21, 0x20, 0x05, -+ 0x14, 0x02, 0x11, 0x01, 0x23, 0x09, 0x07, 0x07, -+ 0x83, 0x01, 0x00, 0x00, 0x6d, 0x03, 0x0c, 0x00, -+ 0x10, 0x00, 0x00, 0x3c, 0x21, 0x00, 0x60, 0x01, -+ 0x02, 0x03, 0x67, 0xd8, 0x5d, 0xc4, 0x01, 0x00, -+ 0x00, 0x00, 0xe2, 0x00, 0xca, 0xe3, 0x05, 0x00, -+ 0x00, 0xe3, 0x06, 0x01, 0x00, 0xe2, 0x0d, 0x5f, -+ 0xa3, 0x66, 0x00, 0xa0, 0xf0, 0x70, 0x1f, 0x80, -+ 0x30, 0x20, 0x35, 0x00, 0xc0, 0x1c, 0x32, 0x00, -+ 0x00, 0x1e, 0x1a, 0x36, 0x80, 0xa0, 0x70, 0x38, -+ 0x1f, 0x40, 0x30, 0x20, 0x35, 0x00, 0xc0, 0x1c, -+ 0x32, 0x00, 0x00, 0x1a, 0x1a, 0x1d, 0x00, 0x80, -+ 0x51, 0xd0, 0x1c, 0x20, 0x40, 0x80, 0x35, 0x00, -+ 0xc0, 0x1c, 0x32, 0x00, 0x00, 0x1c, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1 -+}; -+ -+static void hdmirx_load_default_edid(struct snps_hdmirx_dev *hdmirx_dev) -+{ -+ struct v4l2_edid def_edid; -+ -+ hdmirx_hpd_ctrl(hdmirx_dev, false); -+ -+ /* disable hpd and write edid */ -+ def_edid.pad = 0; -+ def_edid.start_block = 0; -+ def_edid.blocks = EDID_NUM_BLOCKS_MAX; -+ -+ if (IS_ENABLED(CONFIG_VIDEO_SYNOPSYS_HDMIRX_LOAD_DEFAULT_EDID)) -+ def_edid.edid = edid_default; -+ else -+ def_edid.edid = hdmirx_dev->edid; -+ -+ hdmirx_write_edid(hdmirx_dev, &def_edid); -+ -+ if (tx_5v_power_present(hdmirx_dev)) -+ hdmirx_hpd_ctrl(hdmirx_dev, true); -+} -+ -+static void hdmirx_disable_irq(struct device *dev) -+{ -+ struct snps_hdmirx_dev *hdmirx_dev = dev_get_drvdata(dev); -+ -+ disable_irq(hdmirx_dev->hdmi_irq); -+ disable_irq(hdmirx_dev->dma_irq); -+ disable_irq(hdmirx_dev->det_irq); -+ -+ cancel_delayed_work_sync(&hdmirx_dev->delayed_work_hotplug); -+ cancel_delayed_work_sync(&hdmirx_dev->delayed_work_res_change); -+} -+ -+static int hdmirx_disable(struct device *dev) -+{ -+ struct snps_hdmirx_dev *hdmirx_dev = dev_get_drvdata(dev); -+ struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; -+ -+ clk_bulk_disable_unprepare(hdmirx_dev->num_clks, hdmirx_dev->clks); -+ -+ v4l2_dbg(2, debug, v4l2_dev, "%s: suspend\n", __func__); -+ -+ return pinctrl_pm_select_sleep_state(dev); -+} -+ -+static void hdmirx_enable_irq(struct device *dev) -+{ -+ struct snps_hdmirx_dev *hdmirx_dev = dev_get_drvdata(dev); -+ -+ enable_irq(hdmirx_dev->hdmi_irq); -+ enable_irq(hdmirx_dev->dma_irq); -+ enable_irq(hdmirx_dev->det_irq); -+ -+ queue_delayed_work(system_unbound_wq, &hdmirx_dev->delayed_work_hotplug, -+ msecs_to_jiffies(20)); -+} -+ -+static int hdmirx_enable(struct device *dev) -+{ -+ struct snps_hdmirx_dev *hdmirx_dev = dev_get_drvdata(dev); -+ struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; -+ int ret; -+ -+ v4l2_dbg(2, debug, v4l2_dev, "%s: resume\n", __func__); -+ ret = pinctrl_pm_select_default_state(dev); -+ if (ret < 0) -+ return ret; -+ -+ ret = clk_bulk_prepare_enable(hdmirx_dev->num_clks, hdmirx_dev->clks); -+ if (ret) { -+ dev_err(dev, "failed to enable hdmirx bulk clks: %d\n", ret); -+ return ret; -+ } -+ -+ reset_control_bulk_assert(HDMIRX_NUM_RST, hdmirx_dev->resets); -+ usleep_range(150, 160); -+ reset_control_bulk_deassert(HDMIRX_NUM_RST, hdmirx_dev->resets); -+ usleep_range(150, 160); -+ -+ return 0; -+} -+ -+static int hdmirx_suspend(struct device *dev) -+{ -+ hdmirx_disable_irq(dev); -+ -+ return hdmirx_disable(dev); -+} -+ -+static int hdmirx_resume(struct device *dev) -+{ -+ int ret = hdmirx_enable(dev); -+ -+ if (ret) -+ return ret; -+ -+ hdmirx_enable_irq(dev); -+ -+ return 0; -+} -+ -+static const struct dev_pm_ops snps_hdmirx_pm_ops = { -+ SET_SYSTEM_SLEEP_PM_OPS(hdmirx_suspend, hdmirx_resume) -+}; -+ -+static int hdmirx_setup_irq(struct snps_hdmirx_dev *hdmirx_dev, -+ struct platform_device *pdev) -+{ -+ struct device *dev = hdmirx_dev->dev; -+ int ret, irq; -+ -+ irq = platform_get_irq_byname(pdev, "hdmi"); -+ if (irq < 0) { -+ dev_err_probe(dev, irq, "failed to get hdmi irq\n"); -+ return irq; -+ } -+ -+ irq_set_status_flags(irq, IRQ_NOAUTOEN); -+ -+ hdmirx_dev->hdmi_irq = irq; -+ ret = devm_request_irq(dev, irq, hdmirx_hdmi_irq_handler, 0, -+ "rk_hdmirx-hdmi", hdmirx_dev); -+ if (ret) { -+ dev_err_probe(dev, ret, "failed to request hdmi irq\n"); -+ return ret; -+ } -+ -+ irq = platform_get_irq_byname(pdev, "dma"); -+ if (irq < 0) { -+ dev_err_probe(dev, irq, "failed to get dma irq\n"); -+ return irq; -+ } -+ -+ irq_set_status_flags(irq, IRQ_NOAUTOEN); -+ -+ hdmirx_dev->dma_irq = irq; -+ ret = devm_request_threaded_irq(dev, irq, NULL, hdmirx_dma_irq_handler, -+ IRQF_ONESHOT, "rk_hdmirx-dma", -+ hdmirx_dev); -+ if (ret) { -+ dev_err_probe(dev, ret, "failed to request dma irq\n"); -+ return ret; -+ } -+ -+ irq = gpiod_to_irq(hdmirx_dev->detect_5v_gpio); -+ if (irq < 0) { -+ dev_err_probe(dev, irq, "failed to get hdmirx-5v irq\n"); -+ return irq; -+ } -+ -+ irq_set_status_flags(irq, IRQ_NOAUTOEN); -+ -+ hdmirx_dev->det_irq = irq; -+ ret = devm_request_irq(dev, irq, hdmirx_5v_det_irq_handler, -+ IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, -+ "rk_hdmirx-5v", hdmirx_dev); -+ if (ret) { -+ dev_err_probe(dev, ret, "failed to request hdmirx-5v irq\n"); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int hdmirx_register_cec(struct snps_hdmirx_dev *hdmirx_dev, -+ struct platform_device *pdev) -+{ -+ struct device *dev = hdmirx_dev->dev; -+ struct hdmirx_cec_data cec_data; -+ int irq; -+ -+ irq = platform_get_irq_byname(pdev, "cec"); -+ if (irq < 0) { -+ dev_err_probe(dev, irq, "failed to get cec irq\n"); -+ return irq; -+ } -+ -+ hdmirx_dev->cec_notifier = cec_notifier_conn_register(dev, NULL, NULL); -+ if (!hdmirx_dev->cec_notifier) -+ return -EINVAL; -+ -+ cec_data.hdmirx = hdmirx_dev; -+ cec_data.dev = hdmirx_dev->dev; -+ cec_data.ops = &hdmirx_cec_ops; -+ cec_data.irq = irq; -+ -+ hdmirx_dev->cec = snps_hdmirx_cec_register(&cec_data); -+ if (!hdmirx_dev->cec) { -+ cec_notifier_conn_unregister(hdmirx_dev->cec_notifier); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int hdmirx_probe(struct platform_device *pdev) -+{ -+ struct snps_hdmirx_dev *hdmirx_dev; -+ struct device *dev = &pdev->dev; -+ struct v4l2_ctrl_handler *hdl; -+ struct hdmirx_stream *stream; -+ struct v4l2_device *v4l2_dev; -+ int ret; -+ -+ hdmirx_dev = devm_kzalloc(dev, sizeof(*hdmirx_dev), GFP_KERNEL); -+ if (!hdmirx_dev) -+ return -ENOMEM; -+ -+ ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32)); -+ if (ret) -+ return ret; -+ -+ hdmirx_dev->dev = dev; -+ dev_set_drvdata(dev, hdmirx_dev); -+ -+ ret = hdmirx_parse_dt(hdmirx_dev); -+ if (ret) -+ return ret; -+ -+ ret = hdmirx_setup_irq(hdmirx_dev, pdev); -+ if (ret) -+ return ret; -+ -+ hdmirx_dev->regs = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(hdmirx_dev->regs)) -+ return dev_err_probe(dev, PTR_ERR(hdmirx_dev->regs), -+ "failed to remap regs resource\n"); -+ -+ mutex_init(&hdmirx_dev->stream_lock); -+ mutex_init(&hdmirx_dev->work_lock); -+ spin_lock_init(&hdmirx_dev->rst_lock); -+ -+ init_completion(&hdmirx_dev->cr_write_done); -+ init_completion(&hdmirx_dev->timer_base_lock); -+ init_completion(&hdmirx_dev->avi_pkt_rcv); -+ -+ INIT_DELAYED_WORK(&hdmirx_dev->delayed_work_hotplug, -+ hdmirx_delayed_work_hotplug); -+ INIT_DELAYED_WORK(&hdmirx_dev->delayed_work_res_change, -+ hdmirx_delayed_work_res_change); -+ -+ hdmirx_dev->cur_fmt_fourcc = V4L2_PIX_FMT_BGR24; -+ hdmirx_dev->timings = cea640x480; -+ -+ hdmirx_enable(dev); -+ hdmirx_init(hdmirx_dev); -+ -+ v4l2_dev = &hdmirx_dev->v4l2_dev; -+ strscpy(v4l2_dev->name, dev_name(dev), sizeof(v4l2_dev->name)); -+ -+ hdl = &hdmirx_dev->hdl; -+ v4l2_ctrl_handler_init(hdl, 3); -+ -+ hdmirx_dev->detect_tx_5v_ctrl = v4l2_ctrl_new_std(hdl, NULL, -+ V4L2_CID_DV_RX_POWER_PRESENT, -+ 0, 1, 0, 0); -+ -+ hdmirx_dev->rgb_range = v4l2_ctrl_new_std_menu(hdl, NULL, -+ V4L2_CID_DV_RX_RGB_RANGE, -+ V4L2_DV_RGB_RANGE_FULL, 0, -+ V4L2_DV_RGB_RANGE_AUTO); -+ -+ hdmirx_dev->rgb_range->flags |= V4L2_CTRL_FLAG_READ_ONLY; -+ -+ hdmirx_dev->content_type = -+ v4l2_ctrl_new_std_menu(hdl, NULL, V4L2_CID_DV_RX_IT_CONTENT_TYPE, -+ V4L2_DV_IT_CONTENT_TYPE_NO_ITC, 0, -+ V4L2_DV_IT_CONTENT_TYPE_NO_ITC); -+ -+ if (hdl->error) { -+ dev_err(dev, "v4l2 ctrl handler init failed\n"); -+ ret = hdl->error; -+ goto err_pm; -+ } -+ hdmirx_dev->v4l2_dev.ctrl_handler = hdl; -+ -+ ret = v4l2_device_register(dev, &hdmirx_dev->v4l2_dev); -+ if (ret < 0) { -+ dev_err(dev, "register v4l2 device failed\n"); -+ goto err_hdl; -+ } -+ -+ stream = &hdmirx_dev->stream; -+ stream->hdmirx_dev = hdmirx_dev; -+ ret = hdmirx_register_stream_vdev(stream); -+ if (ret < 0) { -+ dev_err(dev, "register video device failed\n"); -+ goto err_unreg_v4l2_dev; -+ } -+ -+ ret = hdmirx_register_cec(hdmirx_dev, pdev); -+ if (ret) -+ goto err_unreg_video_dev; -+ -+ hdmirx_load_default_edid(hdmirx_dev); -+ -+ hdmirx_enable_irq(dev); -+ -+ return 0; -+ -+err_unreg_video_dev: -+ video_unregister_device(&hdmirx_dev->stream.vdev); -+err_unreg_v4l2_dev: -+ v4l2_device_unregister(&hdmirx_dev->v4l2_dev); -+err_hdl: -+ v4l2_ctrl_handler_free(&hdmirx_dev->hdl); -+err_pm: -+ hdmirx_disable(dev); -+ -+ return ret; -+} -+ -+static void hdmirx_remove(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct snps_hdmirx_dev *hdmirx_dev = dev_get_drvdata(dev); -+ -+ snps_hdmirx_cec_unregister(hdmirx_dev->cec); -+ cec_notifier_conn_unregister(hdmirx_dev->cec_notifier); -+ -+ hdmirx_disable_irq(dev); -+ -+ video_unregister_device(&hdmirx_dev->stream.vdev); -+ v4l2_ctrl_handler_free(&hdmirx_dev->hdl); -+ v4l2_device_unregister(&hdmirx_dev->v4l2_dev); -+ -+ hdmirx_disable(dev); -+ -+ reset_control_bulk_assert(HDMIRX_NUM_RST, hdmirx_dev->resets); -+ -+ of_reserved_mem_device_release(dev); -+} -+ -+static const struct of_device_id hdmirx_id[] = { -+ { .compatible = "rockchip,rk3588-hdmirx-ctrler" }, -+ { }, -+}; -+MODULE_DEVICE_TABLE(of, hdmirx_id); -+ -+static struct platform_driver hdmirx_driver = { -+ .probe = hdmirx_probe, -+ .remove = hdmirx_remove, -+ .driver = { -+ .name = "snps_hdmirx", -+ .of_match_table = hdmirx_id, -+ .pm = &snps_hdmirx_pm_ops, -+ } -+}; -+module_platform_driver(hdmirx_driver); -+ -+MODULE_DESCRIPTION("Synopsys HDMI Receiver Driver"); -+MODULE_AUTHOR("Dingxian Wen <shawn.wen@rock-chips.com>"); -+MODULE_AUTHOR("Shreeya Patel <shreeya.patel@collabora.com>"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.h b/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.h -new file mode 100644 -index 000000000000..220ab99ca611 ---- /dev/null -+++ b/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.h -@@ -0,0 +1,394 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (c) 2021 Rockchip Electronics Co. Ltd. -+ * -+ * Author: Dingxian Wen <shawn.wen@rock-chips.com> -+ */ -+ -+#ifndef DW_HDMIRX_H -+#define DW_HDMIRX_H -+ -+#include <linux/bitops.h> -+ -+#define UPDATE(x, h, l) (((x) << (l)) & GENMASK((h), (l))) -+#define HIWORD_UPDATE(v, h, l) (((v) << (l)) | (GENMASK((h), (l)) << 16)) -+ -+/* SYS_GRF */ -+#define SYS_GRF_SOC_CON1 0x0304 -+#define HDMIRXPHY_SRAM_EXT_LD_DONE BIT(1) -+#define HDMIRXPHY_SRAM_BYPASS BIT(0) -+#define SYS_GRF_SOC_STATUS1 0x0384 -+#define HDMIRXPHY_SRAM_INIT_DONE BIT(10) -+#define SYS_GRF_CHIP_ID 0x0600 -+ -+/* VO1_GRF */ -+#define VO1_GRF_VO1_CON2 0x0008 -+#define HDMIRX_SDAIN_MSK BIT(2) -+#define HDMIRX_SCLIN_MSK BIT(1) -+ -+/* HDMIRX PHY */ -+#define SUP_DIG_ANA_CREGS_SUP_ANA_NC 0x004f -+ -+#define LANE0_DIG_ASIC_RX_OVRD_OUT_0 0x100f -+#define LANE1_DIG_ASIC_RX_OVRD_OUT_0 0x110f -+#define LANE2_DIG_ASIC_RX_OVRD_OUT_0 0x120f -+#define LANE3_DIG_ASIC_RX_OVRD_OUT_0 0x130f -+#define ASIC_ACK_OVRD_EN BIT(1) -+#define ASIC_ACK BIT(0) -+ -+#define LANE0_DIG_RX_VCOCAL_RX_VCO_CAL_CTRL_2 0x104a -+#define LANE1_DIG_RX_VCOCAL_RX_VCO_CAL_CTRL_2 0x114a -+#define LANE2_DIG_RX_VCOCAL_RX_VCO_CAL_CTRL_2 0x124a -+#define LANE3_DIG_RX_VCOCAL_RX_VCO_CAL_CTRL_2 0x134a -+#define FREQ_TUNE_START_VAL_MASK GENMASK(9, 0) -+#define FREQ_TUNE_START_VAL(x) UPDATE(x, 9, 0) -+ -+#define HDMIPCS_DIG_CTRL_PATH_MAIN_FSM_FSM_CONFIG 0x20c4 -+#define HDMIPCS_DIG_CTRL_PATH_MAIN_FSM_ADAPT_REF_FOM 0x20c7 -+#define HDMIPCS_DIG_CTRL_PATH_MAIN_FSM_RATE_CALC_HDMI14_CDR_SETTING_3_REG 0x20e9 -+#define CDR_SETTING_BOUNDARY_3_DEFAULT 0x52da -+#define HDMIPCS_DIG_CTRL_PATH_MAIN_FSM_RATE_CALC_HDMI14_CDR_SETTING_4_REG 0x20ea -+#define CDR_SETTING_BOUNDARY_4_DEFAULT 0x43cd -+#define HDMIPCS_DIG_CTRL_PATH_MAIN_FSM_RATE_CALC_HDMI14_CDR_SETTING_5_REG 0x20eb -+#define CDR_SETTING_BOUNDARY_5_DEFAULT 0x35b3 -+#define HDMIPCS_DIG_CTRL_PATH_MAIN_FSM_RATE_CALC_HDMI14_CDR_SETTING_6_REG 0x20fb -+#define CDR_SETTING_BOUNDARY_6_DEFAULT 0x2799 -+#define HDMIPCS_DIG_CTRL_PATH_MAIN_FSM_RATE_CALC_HDMI14_CDR_SETTING_7_REG 0x20fc -+#define CDR_SETTING_BOUNDARY_7_DEFAULT 0x1b65 -+ -+#define RAWLANE0_DIG_PCS_XF_RX_OVRD_OUT 0x300e -+#define RAWLANE1_DIG_PCS_XF_RX_OVRD_OUT 0x310e -+#define RAWLANE2_DIG_PCS_XF_RX_OVRD_OUT 0x320e -+#define RAWLANE3_DIG_PCS_XF_RX_OVRD_OUT 0x330e -+#define PCS_ACK_WRITE_SELECT BIT(14) -+#define PCS_EN_CTL BIT(1) -+#define PCS_ACK BIT(0) -+ -+#define RAWLANE0_DIG_AON_FAST_FLAGS 0x305c -+#define RAWLANE1_DIG_AON_FAST_FLAGS 0x315c -+#define RAWLANE2_DIG_AON_FAST_FLAGS 0x325c -+#define RAWLANE3_DIG_AON_FAST_FLAGS 0x335c -+ -+/* HDMIRX Ctrler */ -+#define GLOBAL_SWRESET_REQUEST 0x0020 -+#define DATAPATH_SWRESETREQ BIT(12) -+#define GLOBAL_SWENABLE 0x0024 -+#define PHYCTRL_ENABLE BIT(21) -+#define CEC_ENABLE BIT(16) -+#define TMDS_ENABLE BIT(13) -+#define DATAPATH_ENABLE BIT(12) -+#define PKTFIFO_ENABLE BIT(11) -+#define AVPUNIT_ENABLE BIT(8) -+#define MAIN_ENABLE BIT(0) -+#define GLOBAL_TIMER_REF_BASE 0x0028 -+#define CORE_CONFIG 0x0050 -+#define CMU_CONFIG0 0x0060 -+#define TMDSQPCLK_STABLE_FREQ_MARGIN_MASK GENMASK(30, 16) -+#define TMDSQPCLK_STABLE_FREQ_MARGIN(x) UPDATE(x, 30, 16) -+#define AUDCLK_STABLE_FREQ_MARGIN_MASK GENMASK(11, 9) -+#define AUDCLK_STABLE_FREQ_MARGIN(x) UPDATE(x, 11, 9) -+#define CMU_STATUS 0x007c -+#define TMDSQPCLK_LOCKED_ST BIT(4) -+#define CMU_TMDSQPCLK_FREQ 0x0084 -+#define PHY_CONFIG 0x00c0 -+#define LDO_AFE_PROG_MASK GENMASK(24, 23) -+#define LDO_AFE_PROG(x) UPDATE(x, 24, 23) -+#define LDO_PWRDN BIT(21) -+#define TMDS_CLOCK_RATIO BIT(16) -+#define RXDATA_WIDTH BIT(15) -+#define REFFREQ_SEL_MASK GENMASK(11, 9) -+#define REFFREQ_SEL(x) UPDATE(x, 11, 9) -+#define HDMI_DISABLE BIT(8) -+#define PHY_PDDQ BIT(1) -+#define PHY_RESET BIT(0) -+#define PHY_STATUS 0x00c8 -+#define HDMI_DISABLE_ACK BIT(1) -+#define PDDQ_ACK BIT(0) -+#define PHYCREG_CONFIG0 0x00e0 -+#define PHYCREG_CR_PARA_SELECTION_MODE_MASK GENMASK(1, 0) -+#define PHYCREG_CR_PARA_SELECTION_MODE(x) UPDATE(x, 1, 0) -+#define PHYCREG_CONFIG1 0x00e4 -+#define PHYCREG_CONFIG2 0x00e8 -+#define PHYCREG_CONFIG3 0x00ec -+#define PHYCREG_CONTROL 0x00f0 -+#define PHYCREG_CR_PARA_WRITE_P BIT(1) -+#define PHYCREG_CR_PARA_READ_P BIT(0) -+#define PHYCREG_STATUS 0x00f4 -+ -+#define MAINUNIT_STATUS 0x0150 -+#define TMDSVALID_STABLE_ST BIT(1) -+#define DESCRAND_EN_CONTROL 0x0210 -+#define SCRAMB_EN_SEL_QST_MASK GENMASK(1, 0) -+#define SCRAMB_EN_SEL_QST(x) UPDATE(x, 1, 0) -+#define DESCRAND_SYNC_CONTROL 0x0214 -+#define RECOVER_UNSYNC_STREAM_QST BIT(0) -+#define DESCRAND_SYNC_SEQ_CONFIG 0x022c -+#define DESCRAND_SYNC_SEQ_ERR_CNT_EN BIT(0) -+#define DESCRAND_SYNC_SEQ_STATUS 0x0234 -+#define DEFRAMER_CONFIG0 0x0270 -+#define VS_CNT_THR_QST_MASK GENMASK(27, 20) -+#define VS_CNT_THR_QST(x) UPDATE(x, 27, 20) -+#define HS_POL_QST_MASK GENMASK(19, 18) -+#define HS_POL_QST(x) UPDATE(x, 19, 18) -+#define VS_POL_QST_MASK GENMASK(17, 16) -+#define VS_POL_QST(x) UPDATE(x, 17, 16) -+#define VS_REMAPFILTER_EN_QST BIT(8) -+#define VS_FILTER_ORDER_QST_MASK GENMASK(1, 0) -+#define VS_FILTER_ORDER_QST(x) UPDATE(x, 1, 0) -+#define DEFRAMER_VSYNC_CNT_CLEAR 0x0278 -+#define VSYNC_CNT_CLR_P BIT(0) -+#define DEFRAMER_STATUS 0x027c -+#define OPMODE_STS_MASK GENMASK(6, 4) -+#define I2C_SLAVE_CONFIG1 0x0164 -+#define I2C_SDA_OUT_HOLD_VALUE_QST_MASK GENMASK(15, 8) -+#define I2C_SDA_OUT_HOLD_VALUE_QST(x) UPDATE(x, 15, 8) -+#define I2C_SDA_IN_HOLD_VALUE_QST_MASK GENMASK(7, 0) -+#define I2C_SDA_IN_HOLD_VALUE_QST(x) UPDATE(x, 7, 0) -+#define OPMODE_STS_MASK GENMASK(6, 4) -+#define REPEATER_QST BIT(28) -+#define FASTREAUTH_QST BIT(27) -+#define FEATURES_1DOT1_QST BIT(26) -+#define FASTI2C_QST BIT(25) -+#define EESS_CTL_THR_QST_MASK GENMASK(19, 16) -+#define EESS_CTL_THR_QST(x) UPDATE(x, 19, 16) -+#define OESS_CTL3_THR_QST_MASK GENMASK(11, 8) -+#define OESS_CTL3_THR_QST(x) UPDATE(x, 11, 8) -+#define EESS_OESS_SEL_QST_MASK GENMASK(5, 4) -+#define EESS_OESS_SEL_QST(x) UPDATE(x, 5, 4) -+#define KEY_DECRYPT_EN_QST BIT(0) -+#define KEY_DECRYPT_SEED_QST_MASK GENMASK(15, 0) -+#define KEY_DECRYPT_SEED_QST(x) UPDATE(x, 15, 0) -+#define HDCP_INT_CLEAR 0x50d8 -+#define HDCP_1_INT_CLEAR 0x50e8 -+#define HDCP2_CONFIG 0x02f0 -+#define HDCP2_SWITCH_OVR_VALUE BIT(2) -+#define HDCP2_SWITCH_OVR_EN BIT(1) -+ -+#define VIDEO_CONFIG2 0x042c -+#define VPROC_VSYNC_POL_OVR_VALUE BIT(19) -+#define VPROC_VSYNC_POL_OVR_EN BIT(18) -+#define VPROC_HSYNC_POL_OVR_VALUE BIT(17) -+#define VPROC_HSYNC_POL_OVR_EN BIT(16) -+#define VPROC_FMT_OVR_VALUE_MASK GENMASK(6, 4) -+#define VPROC_FMT_OVR_VALUE(x) UPDATE(x, 6, 4) -+#define VPROC_FMT_OVR_EN BIT(0) -+ -+#define AFIFO_FILL_RESTART BIT(0) -+#define AFIFO_INIT_P BIT(0) -+#define AFIFO_THR_LOW_QST_MASK GENMASK(25, 16) -+#define AFIFO_THR_LOW_QST(x) UPDATE(x, 25, 16) -+#define AFIFO_THR_HIGH_QST_MASK GENMASK(9, 0) -+#define AFIFO_THR_HIGH_QST(x) UPDATE(x, 9, 0) -+#define AFIFO_THR_MUTE_LOW_QST_MASK GENMASK(25, 16) -+#define AFIFO_THR_MUTE_LOW_QST(x) UPDATE(x, 25, 16) -+#define AFIFO_THR_MUTE_HIGH_QST_MASK GENMASK(9, 0) -+#define AFIFO_THR_MUTE_HIGH_QST(x) UPDATE(x, 9, 0) -+ -+#define AFIFO_UNDERFLOW_ST BIT(25) -+#define AFIFO_OVERFLOW_ST BIT(24) -+ -+#define SPEAKER_ALLOC_OVR_EN BIT(16) -+#define I2S_BPCUV_EN BIT(4) -+#define SPDIF_EN BIT(2) -+#define I2S_EN BIT(1) -+#define AFIFO_THR_PASS_DEMUTEMASK_N BIT(24) -+#define AVMUTE_DEMUTEMASK_N BIT(16) -+#define AFIFO_THR_MUTE_LOW_MUTEMASK_N BIT(9) -+#define AFIFO_THR_MUTE_HIGH_MUTEMASK_N BIT(8) -+#define AVMUTE_MUTEMASK_N BIT(0) -+#define SCDC_CONFIG 0x0580 -+#define HPDLOW BIT(1) -+#define POWERPROVIDED BIT(0) -+#define SCDC_REGBANK_STATUS1 0x058c -+#define SCDC_TMDSBITCLKRATIO BIT(1) -+#define SCDC_REGBANK_STATUS3 0x0594 -+#define SCDC_REGBANK_CONFIG0 0x05c0 -+#define SCDC_SINKVERSION_QST_MASK GENMASK(7, 0) -+#define SCDC_SINKVERSION_QST(x) UPDATE(x, 7, 0) -+#define AGEN_LAYOUT BIT(4) -+#define AGEN_SPEAKER_ALLOC GENMASK(15, 8) -+ -+#define CED_CONFIG 0x0760 -+#define CED_VIDDATACHECKEN_QST BIT(27) -+#define CED_DATAISCHECKEN_QST BIT(26) -+#define CED_GBCHECKEN_QST BIT(25) -+#define CED_CTRLCHECKEN_QST BIT(24) -+#define CED_CHLOCKMAXER_QST_MASK GENMASK(14, 0) -+#define CED_CHLOCKMAXER_QST(x) UPDATE(x, 14, 0) -+#define CED_DYN_CONFIG 0x0768 -+#define CED_DYN_CONTROL 0x076c -+#define PKTEX_BCH_ERRFILT_CONFIG 0x07c4 -+#define PKTEX_CHKSUM_ERRFILT_CONFIG 0x07c8 -+ -+#define PKTDEC_ACR_PH2_1 0x1100 -+#define PKTDEC_ACR_PB3_0 0x1104 -+#define PKTDEC_ACR_PB7_4 0x1108 -+#define PKTDEC_AVIIF_PH2_1 0x1200 -+#define PKTDEC_AVIIF_PB3_0 0x1204 -+#define PKTDEC_AVIIF_PB7_4 0x1208 -+#define VIC_VAL_MASK GENMASK(6, 0) -+#define PKTDEC_AVIIF_PB11_8 0x120c -+#define PKTDEC_AVIIF_PB15_12 0x1210 -+#define PKTDEC_AVIIF_PB19_16 0x1214 -+#define PKTDEC_AVIIF_PB23_20 0x1218 -+#define PKTDEC_AVIIF_PB27_24 0x121c -+ -+#define PKTFIFO_CONFIG 0x1500 -+#define PKTFIFO_STORE_FILT_CONFIG 0x1504 -+#define PKTFIFO_THR_CONFIG0 0x1508 -+#define PKTFIFO_THR_CONFIG1 0x150c -+#define PKTFIFO_CONTROL 0x1510 -+ -+#define VMON_STATUS1 0x1580 -+#define VMON_STATUS2 0x1584 -+#define VMON_STATUS3 0x1588 -+#define VMON_STATUS4 0x158c -+#define VMON_STATUS5 0x1590 -+#define VMON_STATUS6 0x1594 -+#define VMON_STATUS7 0x1598 -+#define VMON_ILACE_DETECT BIT(4) -+ -+#define CEC_TX_CONTROL 0x2000 -+#define CEC_STATUS 0x2004 -+#define CEC_CONFIG 0x2008 -+#define RX_AUTO_DRIVE_ACKNOWLEDGE BIT(9) -+#define CEC_ADDR 0x200c -+#define CEC_TX_COUNT 0x2020 -+#define CEC_TX_DATA3_0 0x2024 -+#define CEC_RX_COUNT_STATUS 0x2040 -+#define CEC_RX_DATA3_0 0x2044 -+#define CEC_LOCK_CONTROL 0x2054 -+#define CEC_RXQUAL_BITTIME_CONFIG 0x2060 -+#define CEC_RX_BITTIME_CONFIG 0x2064 -+#define CEC_TX_BITTIME_CONFIG 0x2068 -+ -+#define DMA_CONFIG1 0x4400 -+#define UV_WID_MASK GENMASK(31, 28) -+#define UV_WID(x) UPDATE(x, 31, 28) -+#define Y_WID_MASK GENMASK(27, 24) -+#define Y_WID(x) UPDATE(x, 27, 24) -+#define DDR_STORE_FORMAT_MASK GENMASK(15, 12) -+#define DDR_STORE_FORMAT(x) UPDATE(x, 15, 12) -+#define ABANDON_EN BIT(0) -+#define DMA_CONFIG2 0x4404 -+#define DMA_CONFIG3 0x4408 -+#define DMA_CONFIG4 0x440c // dma irq en -+#define DMA_CONFIG5 0x4410 // dma irq clear status -+#define LINE_FLAG_INT_EN BIT(8) -+#define HDMIRX_DMA_IDLE_INT BIT(7) -+#define HDMIRX_LOCK_DISABLE_INT BIT(6) -+#define LAST_FRAME_AXI_UNFINISH_INT_EN BIT(5) -+#define FIFO_OVERFLOW_INT_EN BIT(2) -+#define FIFO_UNDERFLOW_INT_EN BIT(1) -+#define HDMIRX_AXI_ERROR_INT_EN BIT(0) -+#define DMA_CONFIG6 0x4414 -+#define RB_SWAP_EN BIT(9) -+#define HSYNC_TOGGLE_EN BIT(5) -+#define VSYNC_TOGGLE_EN BIT(4) -+#define HDMIRX_DMA_EN BIT(1) -+#define DMA_CONFIG7 0x4418 -+#define LINE_FLAG_NUM_MASK GENMASK(31, 16) -+#define LINE_FLAG_NUM(x) UPDATE(x, 31, 16) -+#define LOCK_FRAME_NUM_MASK GENMASK(11, 0) -+#define LOCK_FRAME_NUM(x) UPDATE(x, 11, 0) -+#define DMA_CONFIG8 0x441c -+#define REG_MIRROR_EN BIT(0) -+#define DMA_CONFIG9 0x4420 -+#define DMA_CONFIG10 0x4424 -+#define DMA_CONFIG11 0x4428 -+#define EDID_READ_EN_MASK BIT(8) -+#define EDID_READ_EN(x) UPDATE(x, 8, 8) -+#define EDID_WRITE_EN_MASK BIT(7) -+#define EDID_WRITE_EN(x) UPDATE(x, 7, 7) -+#define EDID_SLAVE_ADDR_MASK GENMASK(6, 0) -+#define EDID_SLAVE_ADDR(x) UPDATE(x, 6, 0) -+#define DMA_STATUS1 0x4430 // dma irq status -+#define DMA_STATUS2 0x4434 -+#define DMA_STATUS3 0x4438 -+#define DMA_STATUS4 0x443c -+#define DMA_STATUS5 0x4440 -+#define DMA_STATUS6 0x4444 -+#define DMA_STATUS7 0x4448 -+#define DMA_STATUS8 0x444c -+#define DMA_STATUS9 0x4450 -+#define DMA_STATUS10 0x4454 -+#define HDMIRX_LOCK BIT(3) -+#define DMA_STATUS11 0x4458 -+#define HDMIRX_TYPE_MASK GENMASK(8, 7) -+#define HDMIRX_COLOR_DEPTH_MASK GENMASK(6, 3) -+#define HDMIRX_FORMAT_MASK GENMASK(2, 0) -+#define DMA_STATUS12 0x445c -+#define DMA_STATUS13 0x4460 -+#define DMA_STATUS14 0x4464 -+ -+#define MAINUNIT_INTVEC_INDEX 0x5000 -+#define MAINUNIT_0_INT_STATUS 0x5010 -+#define CECRX_NOTIFY_ERR BIT(12) -+#define CECRX_EOM BIT(11) -+#define CECTX_DRIVE_ERR BIT(10) -+#define CECRX_BUSY BIT(9) -+#define CECTX_BUSY BIT(8) -+#define CECTX_FRAME_DISCARDED BIT(5) -+#define CECTX_NRETRANSMIT_FAIL BIT(4) -+#define CECTX_LINE_ERR BIT(3) -+#define CECTX_ARBLOST BIT(2) -+#define CECTX_NACK BIT(1) -+#define CECTX_DONE BIT(0) -+#define MAINUNIT_0_INT_MASK_N 0x5014 -+#define MAINUNIT_0_INT_CLEAR 0x5018 -+#define MAINUNIT_0_INT_FORCE 0x501c -+#define TIMER_BASE_LOCKED_IRQ BIT(26) -+#define TMDSQPCLK_OFF_CHG BIT(5) -+#define TMDSQPCLK_LOCKED_CHG BIT(4) -+#define MAINUNIT_1_INT_STATUS 0x5020 -+#define MAINUNIT_1_INT_MASK_N 0x5024 -+#define MAINUNIT_1_INT_CLEAR 0x5028 -+#define MAINUNIT_1_INT_FORCE 0x502c -+#define MAINUNIT_2_INT_STATUS 0x5030 -+#define MAINUNIT_2_INT_MASK_N 0x5034 -+#define MAINUNIT_2_INT_CLEAR 0x5038 -+#define MAINUNIT_2_INT_FORCE 0x503c -+#define PHYCREG_CR_READ_DONE BIT(11) -+#define PHYCREG_CR_WRITE_DONE BIT(10) -+#define TMDSVALID_STABLE_CHG BIT(1) -+ -+#define AVPUNIT_0_INT_STATUS 0x5040 -+#define AVPUNIT_0_INT_MASK_N 0x5044 -+#define AVPUNIT_0_INT_CLEAR 0x5048 -+#define AVPUNIT_0_INT_FORCE 0x504c -+#define CED_DYN_CNT_CH2_IRQ BIT(22) -+#define CED_DYN_CNT_CH1_IRQ BIT(21) -+#define CED_DYN_CNT_CH0_IRQ BIT(20) -+#define AVPUNIT_1_INT_STATUS 0x5050 -+#define DEFRAMER_VSYNC_THR_REACHED_IRQ BIT(1) -+#define AVPUNIT_1_INT_MASK_N 0x5054 -+#define DEFRAMER_VSYNC_THR_REACHED_MASK_N BIT(1) -+#define DEFRAMER_VSYNC_MASK_N BIT(0) -+#define AVPUNIT_1_INT_CLEAR 0x5058 -+#define DEFRAMER_VSYNC_THR_REACHED_CLEAR BIT(1) -+#define PKT_0_INT_STATUS 0x5080 -+#define PKTDEC_ACR_CHG_IRQ BIT(3) -+#define PKT_0_INT_MASK_N 0x5084 -+#define PKTDEC_ACR_CHG_MASK_N BIT(3) -+#define PKT_0_INT_CLEAR 0x5088 -+#define PKT_1_INT_STATUS 0x5090 -+#define PKT_1_INT_MASK_N 0x5094 -+#define PKT_1_INT_CLEAR 0x5098 -+#define PKT_2_INT_STATUS 0x50a0 -+#define PKTDEC_ACR_RCV_IRQ BIT(3) -+#define PKT_2_INT_MASK_N 0x50a4 -+#define PKTDEC_AVIIF_RCV_IRQ BIT(11) -+#define PKTDEC_ACR_RCV_MASK_N BIT(3) -+#define PKT_2_INT_CLEAR 0x50a8 -+#define PKTDEC_AVIIF_RCV_CLEAR BIT(11) -+#define PKTDEC_ACR_RCV_CLEAR BIT(3) -+#define SCDC_INT_STATUS 0x50c0 -+#define SCDC_INT_MASK_N 0x50c4 -+#define SCDC_INT_CLEAR 0x50c8 -+#define SCDCTMDSCCFG_CHG BIT(2) -+ -+#define CEC_INT_STATUS 0x5100 -+#define CEC_INT_MASK_N 0x5104 -+#define CEC_INT_CLEAR 0x5108 -+ -+#endif -diff --git a/drivers/media/platform/synopsys/hdmirx/snps_hdmirx_cec.c b/drivers/media/platform/synopsys/hdmirx/snps_hdmirx_cec.c -new file mode 100644 -index 000000000000..09b89529f0d4 ---- /dev/null -+++ b/drivers/media/platform/synopsys/hdmirx/snps_hdmirx_cec.c -@@ -0,0 +1,283 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (c) 2021 Rockchip Electronics Co. Ltd. -+ * -+ * Author: Shunqing Chen <csq@rock-chips.com> -+ */ -+ -+#include <linux/interrupt.h> -+#include <linux/io.h> -+#include <linux/module.h> -+#include <linux/platform_device.h> -+#include <linux/slab.h> -+ -+#include <media/cec.h> -+#include <media/cec-notifier.h> -+ -+#include "snps_hdmirx.h" -+#include "snps_hdmirx_cec.h" -+ -+static void hdmirx_cec_write(struct hdmirx_cec *cec, int reg, u32 val) -+{ -+ cec->ops->write(cec->hdmirx, reg, val); -+} -+ -+static u32 hdmirx_cec_read(struct hdmirx_cec *cec, int reg) -+{ -+ return cec->ops->read(cec->hdmirx, reg); -+} -+ -+static void hdmirx_cec_update_bits(struct hdmirx_cec *cec, int reg, u32 mask, -+ u32 data) -+{ -+ u32 val = hdmirx_cec_read(cec, reg) & ~mask; -+ -+ val |= (data & mask); -+ hdmirx_cec_write(cec, reg, val); -+} -+ -+static int hdmirx_cec_log_addr(struct cec_adapter *adap, u8 logical_addr) -+{ -+ struct hdmirx_cec *cec = cec_get_drvdata(adap); -+ -+ if (logical_addr == CEC_LOG_ADDR_INVALID) -+ cec->addresses = 0; -+ else -+ cec->addresses |= BIT(logical_addr) | BIT(15); -+ -+ hdmirx_cec_write(cec, CEC_ADDR, cec->addresses); -+ -+ return 0; -+} -+ -+/* signal_free_time is handled by the Synopsys Designware -+ * HDMIRX Controller hardware. -+ */ -+static int hdmirx_cec_transmit(struct cec_adapter *adap, u8 attempts, -+ u32 signal_free_time, struct cec_msg *msg) -+{ -+ struct hdmirx_cec *cec = cec_get_drvdata(adap); -+ u32 data[4] = {0}; -+ int i, data_len, msg_len; -+ -+ msg_len = msg->len; -+ -+ hdmirx_cec_write(cec, CEC_TX_COUNT, msg_len - 1); -+ for (i = 0; i < msg_len; i++) -+ data[i / 4] |= msg->msg[i] << (i % 4) * 8; -+ -+ data_len = DIV_ROUND_UP(msg_len, 4); -+ -+ for (i = 0; i < data_len; i++) -+ hdmirx_cec_write(cec, CEC_TX_DATA3_0 + i * 4, data[i]); -+ -+ hdmirx_cec_write(cec, CEC_TX_CONTROL, 0x1); -+ -+ return 0; -+} -+ -+static irqreturn_t hdmirx_cec_hardirq(int irq, void *data) -+{ -+ struct cec_adapter *adap = data; -+ struct hdmirx_cec *cec = cec_get_drvdata(adap); -+ u32 stat = hdmirx_cec_read(cec, CEC_INT_STATUS); -+ irqreturn_t ret = IRQ_HANDLED; -+ u32 val; -+ -+ if (!stat) -+ return IRQ_NONE; -+ -+ hdmirx_cec_write(cec, CEC_INT_CLEAR, stat); -+ -+ if (stat & CECTX_LINE_ERR) { -+ cec->tx_status = CEC_TX_STATUS_ERROR; -+ cec->tx_done = true; -+ ret = IRQ_WAKE_THREAD; -+ } else if (stat & CECTX_DONE) { -+ cec->tx_status = CEC_TX_STATUS_OK; -+ cec->tx_done = true; -+ ret = IRQ_WAKE_THREAD; -+ } else if (stat & CECTX_NACK) { -+ cec->tx_status = CEC_TX_STATUS_NACK; -+ cec->tx_done = true; -+ ret = IRQ_WAKE_THREAD; -+ } else if (stat & CECTX_ARBLOST) { -+ cec->tx_status = CEC_TX_STATUS_ARB_LOST; -+ cec->tx_done = true; -+ ret = IRQ_WAKE_THREAD; -+ } -+ -+ if (stat & CECRX_EOM) { -+ unsigned int len, i; -+ -+ val = hdmirx_cec_read(cec, CEC_RX_COUNT_STATUS); -+ /* rxbuffer locked status */ -+ if ((val & 0x80)) -+ return ret; -+ -+ len = (val & 0xf) + 1; -+ if (len > sizeof(cec->rx_msg.msg)) -+ len = sizeof(cec->rx_msg.msg); -+ -+ for (i = 0; i < len; i++) { -+ if (!(i % 4)) -+ val = hdmirx_cec_read(cec, CEC_RX_DATA3_0 + i / 4 * 4); -+ cec->rx_msg.msg[i] = (val >> ((i % 4) * 8)) & 0xff; -+ } -+ -+ cec->rx_msg.len = len; -+ smp_wmb(); /* receive RX msg */ -+ cec->rx_done = true; -+ hdmirx_cec_write(cec, CEC_LOCK_CONTROL, 0x1); -+ -+ ret = IRQ_WAKE_THREAD; -+ } -+ -+ return ret; -+} -+ -+static irqreturn_t hdmirx_cec_thread(int irq, void *data) -+{ -+ struct cec_adapter *adap = data; -+ struct hdmirx_cec *cec = cec_get_drvdata(adap); -+ -+ if (cec->tx_done) { -+ cec->tx_done = false; -+ cec_transmit_attempt_done(adap, cec->tx_status); -+ } -+ if (cec->rx_done) { -+ cec->rx_done = false; -+ smp_rmb(); /* RX msg has been received */ -+ cec_received_msg(adap, &cec->rx_msg); -+ } -+ -+ return IRQ_HANDLED; -+} -+ -+static int hdmirx_cec_enable(struct cec_adapter *adap, bool enable) -+{ -+ struct hdmirx_cec *cec = cec_get_drvdata(adap); -+ -+ if (!enable) { -+ hdmirx_cec_write(cec, CEC_INT_MASK_N, 0); -+ hdmirx_cec_write(cec, CEC_INT_CLEAR, 0); -+ if (cec->ops->disable) -+ cec->ops->disable(cec->hdmirx); -+ } else { -+ unsigned int irqs; -+ -+ hdmirx_cec_log_addr(cec->adap, CEC_LOG_ADDR_INVALID); -+ if (cec->ops->enable) -+ cec->ops->enable(cec->hdmirx); -+ hdmirx_cec_update_bits(cec, GLOBAL_SWENABLE, CEC_ENABLE, CEC_ENABLE); -+ -+ irqs = CECTX_LINE_ERR | CECTX_NACK | CECRX_EOM | CECTX_DONE; -+ hdmirx_cec_write(cec, CEC_INT_MASK_N, irqs); -+ } -+ -+ return 0; -+} -+ -+static const struct cec_adap_ops hdmirx_cec_ops = { -+ .adap_enable = hdmirx_cec_enable, -+ .adap_log_addr = hdmirx_cec_log_addr, -+ .adap_transmit = hdmirx_cec_transmit, -+}; -+ -+static void hdmirx_cec_del(void *data) -+{ -+ struct hdmirx_cec *cec = data; -+ -+ cec_delete_adapter(cec->adap); -+} -+ -+struct hdmirx_cec *snps_hdmirx_cec_register(struct hdmirx_cec_data *data) -+{ -+ struct hdmirx_cec *cec; -+ unsigned int irqs; -+ int ret; -+ -+ /* -+ * Our device is just a convenience - we want to link to the real -+ * hardware device here, so that userspace can see the association -+ * between the HDMI hardware and its associated CEC chardev. -+ */ -+ cec = devm_kzalloc(data->dev, sizeof(*cec), GFP_KERNEL); -+ if (!cec) -+ return NULL; -+ -+ cec->dev = data->dev; -+ cec->irq = data->irq; -+ cec->ops = data->ops; -+ cec->hdmirx = data->hdmirx; -+ -+ hdmirx_cec_update_bits(cec, GLOBAL_SWENABLE, CEC_ENABLE, CEC_ENABLE); -+ hdmirx_cec_update_bits(cec, CEC_CONFIG, RX_AUTO_DRIVE_ACKNOWLEDGE, -+ RX_AUTO_DRIVE_ACKNOWLEDGE); -+ -+ hdmirx_cec_write(cec, CEC_TX_COUNT, 0); -+ hdmirx_cec_write(cec, CEC_INT_MASK_N, 0); -+ hdmirx_cec_write(cec, CEC_INT_CLEAR, ~0); -+ -+ cec->adap = cec_allocate_adapter(&hdmirx_cec_ops, cec, "snps-hdmirx", -+ CEC_CAP_DEFAULTS | CEC_CAP_MONITOR_ALL, -+ CEC_MAX_LOG_ADDRS); -+ if (IS_ERR(cec->adap)) { -+ dev_err(cec->dev, "cec adap allocate failed\n"); -+ return NULL; -+ } -+ -+ /* override the module pointer */ -+ cec->adap->owner = THIS_MODULE; -+ -+ ret = devm_add_action(cec->dev, hdmirx_cec_del, cec); -+ if (ret) { -+ cec_delete_adapter(cec->adap); -+ return NULL; -+ } -+ -+ irq_set_status_flags(cec->irq, IRQ_NOAUTOEN); -+ -+ ret = devm_request_threaded_irq(cec->dev, cec->irq, -+ hdmirx_cec_hardirq, -+ hdmirx_cec_thread, IRQF_ONESHOT, -+ "rk_hdmirx_cec", cec->adap); -+ if (ret) { -+ dev_err(cec->dev, "cec irq request failed\n"); -+ return NULL; -+ } -+ -+ cec->notify = cec_notifier_cec_adap_register(cec->dev, -+ NULL, cec->adap); -+ if (!cec->notify) { -+ dev_err(cec->dev, "cec notify register failed\n"); -+ return NULL; -+ } -+ -+ ret = cec_register_adapter(cec->adap, cec->dev); -+ if (ret < 0) { -+ dev_err(cec->dev, "cec register adapter failed\n"); -+ cec_unregister_adapter(cec->adap); -+ return NULL; -+ } -+ -+ irqs = CECTX_LINE_ERR | CECTX_NACK | CECRX_EOM | CECTX_DONE; -+ hdmirx_cec_write(cec, CEC_INT_MASK_N, irqs); -+ -+ /* -+ * CEC documentation says we must not call cec_delete_adapter -+ * after a successful call to cec_register_adapter(). -+ */ -+ devm_remove_action(cec->dev, hdmirx_cec_del, cec); -+ -+ enable_irq(cec->irq); -+ -+ return cec; -+} -+ -+void snps_hdmirx_cec_unregister(struct hdmirx_cec *cec) -+{ -+ disable_irq(cec->irq); -+ -+ cec_unregister_adapter(cec->adap); -+} -diff --git a/drivers/media/platform/synopsys/hdmirx/snps_hdmirx_cec.h b/drivers/media/platform/synopsys/hdmirx/snps_hdmirx_cec.h -new file mode 100644 -index 000000000000..c55c403cdb9f ---- /dev/null -+++ b/drivers/media/platform/synopsys/hdmirx/snps_hdmirx_cec.h -@@ -0,0 +1,44 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (c) 2021 Rockchip Electronics Co. Ltd. -+ * -+ * Author: Shunqing Chen <csq@rock-chips.com> -+ */ -+ -+#ifndef DW_HDMI_RX_CEC_H -+#define DW_HDMI_RX_CEC_H -+ -+struct snps_hdmirx_dev; -+ -+struct hdmirx_cec_ops { -+ void (*write)(struct snps_hdmirx_dev *hdmirx_dev, int reg, u32 val); -+ u32 (*read)(struct snps_hdmirx_dev *hdmirx_dev, int reg); -+ void (*enable)(struct snps_hdmirx_dev *hdmirx); -+ void (*disable)(struct snps_hdmirx_dev *hdmirx); -+}; -+ -+struct hdmirx_cec_data { -+ struct snps_hdmirx_dev *hdmirx; -+ const struct hdmirx_cec_ops *ops; -+ struct device *dev; -+ int irq; -+}; -+ -+struct hdmirx_cec { -+ struct snps_hdmirx_dev *hdmirx; -+ struct device *dev; -+ const struct hdmirx_cec_ops *ops; -+ u32 addresses; -+ struct cec_adapter *adap; -+ struct cec_msg rx_msg; -+ unsigned int tx_status; -+ bool tx_done; -+ bool rx_done; -+ struct cec_notifier *notify; -+ int irq; -+}; -+ -+struct hdmirx_cec *snps_hdmirx_cec_register(struct hdmirx_cec_data *data); -+void snps_hdmirx_cec_unregister(struct hdmirx_cec *cec); -+ -+#endif /* DW_HDMI_RX_CEC_H */ --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0045-arm64-defconfig-Enable-Synopsys-HDMI-receiver.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0045-arm64-defconfig-Enable-Synopsys-HDMI-receiver.patch deleted file mode 100644 index 17b096c613..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0045-arm64-defconfig-Enable-Synopsys-HDMI-receiver.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 07db4ce399ed0c5411629de2b8a1b4cc58c1c777 Mon Sep 17 00:00:00 2001 -From: Sebastian Reichel <sebastian.reichel@collabora.com> -Date: Mon, 29 Jul 2024 17:29:46 +0200 -Subject: [PATCH 45/63] arm64: defconfig: Enable Synopsys HDMI receiver - -The Rockchip RK3588 has a built-in HDMI receiver block from -Synopsys. Let's enable the driver for it. - -Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> ---- - arch/arm64/configs/defconfig | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig -index 0c9dd4af485c..0ec5bc97634a 100644 ---- a/arch/arm64/configs/defconfig -+++ b/arch/arm64/configs/defconfig -@@ -848,6 +848,7 @@ CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC=m - CONFIG_VIDEO_SAMSUNG_S5P_JPEG=m - CONFIG_VIDEO_SAMSUNG_S5P_MFC=m - CONFIG_VIDEO_SUN6I_CSI=m -+CONFIG_VIDEO_SYNOPSYS_HDMIRX=m - CONFIG_VIDEO_TI_J721E_CSI2RX=m - CONFIG_VIDEO_HANTRO=m - CONFIG_VIDEO_IMX219=m --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0046-arm64-dts-rockchip-Enable-HDMI-receiver-on-rock-5b.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0046-arm64-dts-rockchip-Enable-HDMI-receiver-on-rock-5b.patch deleted file mode 100644 index 1b09d3adf9..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0046-arm64-dts-rockchip-Enable-HDMI-receiver-on-rock-5b.patch +++ /dev/null @@ -1,52 +0,0 @@ -From bbdb92a53a8bb60a91e2d556951f4dc6b3b124a9 Mon Sep 17 00:00:00 2001 -From: Sebastian Reichel <sebastian.reichel@collabora.com> -Date: Mon, 29 Jul 2024 17:32:27 +0200 -Subject: [PATCH 46/63] arm64: dts: rockchip: Enable HDMI receiver on rock-5b - -The Rock 5B has a Micro HDMI port, which can be used for receiving -HDMI data. This enables support for it. - -Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> ---- - .../arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts -index 4d84b95235a5..903066a23757 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts -@@ -236,6 +236,18 @@ hdmi0_out_con: endpoint { - }; - }; - -+&hdmi_receiver_cma { -+ status = "okay"; -+}; -+ -+&hdmi_receiver { -+ status = "okay"; -+ hpd-gpios = <&gpio1 RK_PC6 GPIO_ACTIVE_LOW>; -+ pinctrl-0 = <&hdmim1_rx_cec &hdmim1_rx_hpdin &hdmim1_rx_scl &hdmim1_rx_sda &hdmirx_hpd>; -+ pinctrl-names = "default"; -+ memory-region = <&hdmi_receiver_cma>; -+}; -+ - &hdptxphy_hdmi0 { - status = "okay"; - }; -@@ -454,6 +466,12 @@ &pcie3x4 { - }; - - &pinctrl { -+ hdmirx { -+ hdmirx_hpd: hdmirx-5v-detection { -+ rockchip,pins = <1 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ - hym8563 { - hym8563_int: hym8563-int { - rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0047-arm64-dts-rockchip-Enable-HDMI-receiver-on-RK3588-EV.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0047-arm64-dts-rockchip-Enable-HDMI-receiver-on-RK3588-EV.patch deleted file mode 100644 index 88d8328bc1..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0047-arm64-dts-rockchip-Enable-HDMI-receiver-on-RK3588-EV.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 4aa728eaa8d46134b7531ba33459a54a7f9e4254 Mon Sep 17 00:00:00 2001 -From: Sebastian Reichel <sebastian.reichel@collabora.com> -Date: Tue, 30 Jul 2024 15:55:19 +0200 -Subject: [PATCH 47/63] arm64: dts: rockchip: Enable HDMI receiver on RK3588 - EVB1 - -Enable HDMI input port of the RK3588 EVB1. - -Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> ---- - .../boot/dts/rockchip/rk3588-evb1-v10.dts | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts -index 07c77c369b19..7dc3ee6e7eb4 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts -@@ -342,6 +342,18 @@ hdmi0_out_con: endpoint { - }; - }; - -+&hdmi_receiver_cma { -+ status = "okay"; -+}; -+ -+&hdmi_receiver { -+ status = "okay"; -+ hpd-gpios = <&gpio2 RK_PB5 GPIO_ACTIVE_LOW>; -+ pinctrl-0 = <&hdmim1_rx_cec &hdmim1_rx_hpdin &hdmim1_rx_scl &hdmim1_rx_sda &hdmirx_hpd>; -+ pinctrl-names = "default"; -+ memory-region = <&hdmi_receiver_cma>; -+}; -+ - &hdptxphy_hdmi0 { - status = "okay"; - }; -@@ -507,6 +519,12 @@ rtl8211f_rst: rtl8211f-rst { - - }; - -+ hdmirx { -+ hdmirx_hpd: hdmirx-5v-detection { -+ rockchip,pins = <2 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ - hym8563 { - hym8563_int: hym8563-int { - rockchip,pins = <0 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>; --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0048-arm64-defconfig-Enable-default-EDID-for-Synopsys-HDM.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0048-arm64-defconfig-Enable-default-EDID-for-Synopsys-HDM.patch deleted file mode 100644 index 28bc462dd2..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0048-arm64-defconfig-Enable-default-EDID-for-Synopsys-HDM.patch +++ /dev/null @@ -1,29 +0,0 @@ -From c10e3f59edf30d3545df9c22b742567b57b5d64a Mon Sep 17 00:00:00 2001 -From: Dmitry Osipenko <dmitry.osipenko@collabora.com> -Date: Wed, 30 Oct 2024 15:13:30 +0300 -Subject: [PATCH 48/63] arm64: defconfig: Enable default EDID for Synopsys HDMI - receiver - -Make HDMI receiver driver use default EDID, not requiring user to load -EDID manually using v4l-utils. - -Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com> ---- - arch/arm64/configs/defconfig | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig -index 0ec5bc97634a..8ff299e43a33 100644 ---- a/arch/arm64/configs/defconfig -+++ b/arch/arm64/configs/defconfig -@@ -849,6 +849,7 @@ CONFIG_VIDEO_SAMSUNG_S5P_JPEG=m - CONFIG_VIDEO_SAMSUNG_S5P_MFC=m - CONFIG_VIDEO_SUN6I_CSI=m - CONFIG_VIDEO_SYNOPSYS_HDMIRX=m -+CONFIG_VIDEO_SYNOPSYS_HDMIRX_LOAD_DEFAULT_EDID=y - CONFIG_VIDEO_TI_J721E_CSI2RX=m - CONFIG_VIDEO_HANTRO=m - CONFIG_VIDEO_IMX219=m --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0049-regulator-Add-devm_-of_regulator_get.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0049-regulator-Add-devm_-of_regulator_get.patch deleted file mode 100644 index e200491ea1..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0049-regulator-Add-devm_-of_regulator_get.patch +++ /dev/null @@ -1,102 +0,0 @@ -From ec4b2d933bf786274ed59e7180a2f097e12abda0 Mon Sep 17 00:00:00 2001 -From: Sebastian Reichel <sebastian.reichel@collabora.com> -Date: Tue, 22 Oct 2024 15:14:27 +0200 -Subject: [PATCH 49/63] regulator: Add (devm_)of_regulator_get() - -The Rockchip power-domain controller also plans to make use of -per-domain regulators similar to the MediaTek power-domain controller. -Since existing DTs are missing the regulator information, the kernel -should fallback to the automatically created dummy regulator if -necessary. Thus the version without the _optional suffix is needed. - -The Rockchip driver plans to use the managed version, but to be -consistent with existing code the unmanaged version is added at the -same time. - -Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> ---- - drivers/regulator/devres.c | 17 +++++++++++++++++ - drivers/regulator/of_regulator.c | 21 +++++++++++++++++++++ - include/linux/regulator/consumer.h | 6 ++++++ - 3 files changed, 44 insertions(+) - -diff --git a/drivers/regulator/devres.c b/drivers/regulator/devres.c -index 36164aec30e8..a3a3ccc711fc 100644 ---- a/drivers/regulator/devres.c -+++ b/drivers/regulator/devres.c -@@ -771,6 +771,23 @@ static struct regulator *_devm_of_regulator_get(struct device *dev, struct devic - return regulator; - } - -+/** -+ * devm_of_regulator_get - Resource managed of_regulator_get() -+ * @dev: device used for dev_printk() messages and resource lifetime management -+ * @node: device node for regulator "consumer" -+ * @id: supply name or regulator ID. -+ * -+ * Managed of_regulator_get(). Regulators returned from this -+ * function are automatically regulator_put() on driver detach. See -+ * of_regulator_get() for more information. -+ */ -+struct regulator *devm_of_regulator_get(struct device *dev, struct device_node *node, -+ const char *id) -+{ -+ return _devm_of_regulator_get(dev, node, id, NORMAL_GET); -+} -+EXPORT_SYMBOL_GPL(devm_of_regulator_get); -+ - /** - * devm_of_regulator_get_optional - Resource managed of_regulator_get_optional() - * @dev: device used for dev_printk() messages and resource lifetime management -diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c -index 3d85762beda6..31a5bacd99b4 100644 ---- a/drivers/regulator/of_regulator.c -+++ b/drivers/regulator/of_regulator.c -@@ -682,6 +682,27 @@ struct regulator *_of_regulator_get(struct device *dev, struct device_node *node - return _regulator_get_common(r, dev, id, get_type); - } - -+/** -+ * of_regulator_get - get regulator via device tree lookup -+ * @dev: device used for dev_printk() messages -+ * @node: device node for regulator "consumer" -+ * @id: Supply name -+ * -+ * Return: pointer to struct regulator corresponding to the regulator producer, -+ * or PTR_ERR() encoded error number. -+ * -+ * This is intended for use by consumers that want to get a regulator -+ * supply directly from a device node. This will _not_ consider supply -+ * aliases. See regulator_dev_lookup(). -+ */ -+struct regulator *of_regulator_get(struct device *dev, -+ struct device_node *node, -+ const char *id) -+{ -+ return _of_regulator_get(dev, node, id, NORMAL_GET); -+} -+EXPORT_SYMBOL_GPL(of_regulator_get); -+ - /** - * of_regulator_get_optional - get optional regulator via device tree lookup - * @dev: device used for dev_printk() messages -diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h -index 8c3c372ad735..5903ae7444ae 100644 ---- a/include/linux/regulator/consumer.h -+++ b/include/linux/regulator/consumer.h -@@ -169,6 +169,12 @@ void regulator_put(struct regulator *regulator); - void devm_regulator_put(struct regulator *regulator); - - #if IS_ENABLED(CONFIG_OF) -+struct regulator *__must_check of_regulator_get(struct device *dev, -+ struct device_node *node, -+ const char *id); -+struct regulator *__must_check devm_of_regulator_get(struct device *dev, -+ struct device_node *node, -+ const char *id); - struct regulator *__must_check of_regulator_get_optional(struct device *dev, - struct device_node *node, - const char *id); --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0050-pmdomain-rockchip-cleanup-mutex-handling-in-rockchip.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0050-pmdomain-rockchip-cleanup-mutex-handling-in-rockchip.patch deleted file mode 100644 index 96d2793535..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0050-pmdomain-rockchip-cleanup-mutex-handling-in-rockchip.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 317d7b3327b6c86da4d17738bffab068433070ac Mon Sep 17 00:00:00 2001 -From: Sebastian Reichel <sebastian.reichel@collabora.com> -Date: Fri, 6 Sep 2024 17:03:53 +0200 -Subject: [PATCH 50/63] pmdomain: rockchip: cleanup mutex handling in - rockchip_pd_power - -Use the cleanup infrastructure to handle the mutex, which -slightly improve code readability for this function. - -Reviewed-by: Heiko Stuebner <heiko@sntech.de> -Tested-by: Adrian Larumbe <adrian.larumbe@collabora.com> # On Rock 5B -Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> ---- - drivers/pmdomain/rockchip/pm-domains.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - -diff --git a/drivers/pmdomain/rockchip/pm-domains.c b/drivers/pmdomain/rockchip/pm-domains.c -index cb0f93800138..a161ee13c633 100644 ---- a/drivers/pmdomain/rockchip/pm-domains.c -+++ b/drivers/pmdomain/rockchip/pm-domains.c -@@ -574,13 +574,12 @@ static int rockchip_pd_power(struct rockchip_pm_domain *pd, bool power_on) - struct rockchip_pmu *pmu = pd->pmu; - int ret; - -- mutex_lock(&pmu->mutex); -+ guard(mutex)(&pmu->mutex); - - if (rockchip_pmu_domain_is_on(pd) != power_on) { - ret = clk_bulk_enable(pd->num_clks, pd->clks); - if (ret < 0) { - dev_err(pmu->dev, "failed to enable clocks\n"); -- mutex_unlock(&pmu->mutex); - return ret; - } - -@@ -606,7 +605,6 @@ static int rockchip_pd_power(struct rockchip_pm_domain *pd, bool power_on) - clk_bulk_disable(pd->num_clks, pd->clks); - } - -- mutex_unlock(&pmu->mutex); - return 0; - } - --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0051-pmdomain-rockchip-forward-rockchip_do_pmu_set_power_.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0051-pmdomain-rockchip-forward-rockchip_do_pmu_set_power_.patch deleted file mode 100644 index bd6a0e363f..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0051-pmdomain-rockchip-forward-rockchip_do_pmu_set_power_.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 6d81e133ffcfdbdb5e1d694c791807e636f08a51 Mon Sep 17 00:00:00 2001 -From: Sebastian Reichel <sebastian.reichel@collabora.com> -Date: Fri, 6 Sep 2024 16:47:47 +0200 -Subject: [PATCH 51/63] pmdomain: rockchip: forward - rockchip_do_pmu_set_power_domain errors - -Currently rockchip_do_pmu_set_power_domain prints a warning if there -have been errors turning on the power domain, but it does not return -any errors and rockchip_pd_power() tries to continue setting up the -QOS registers. This usually results in accessing unpowered registers, -which triggers an SError and a full system hang. - -This improves the error handling by forwarding the error to avoid -kernel panics. - -Reviewed-by: Heiko Stuebner <heiko@sntech.de> -Tested-by: Adrian Larumbe <adrian.larumbe@collabora.com> # On Rock 5B -Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> ---- - drivers/pmdomain/rockchip/pm-domains.c | 34 +++++++++++++++++--------- - 1 file changed, 22 insertions(+), 12 deletions(-) - -diff --git a/drivers/pmdomain/rockchip/pm-domains.c b/drivers/pmdomain/rockchip/pm-domains.c -index a161ee13c633..8f440f2883db 100644 ---- a/drivers/pmdomain/rockchip/pm-domains.c -+++ b/drivers/pmdomain/rockchip/pm-domains.c -@@ -533,16 +533,17 @@ static int rockchip_pmu_domain_mem_reset(struct rockchip_pm_domain *pd) - return ret; - } - --static void rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *pd, -- bool on) -+static int rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *pd, -+ bool on) - { - struct rockchip_pmu *pmu = pd->pmu; - struct generic_pm_domain *genpd = &pd->genpd; - u32 pd_pwr_offset = pd->info->pwr_offset; - bool is_on, is_mem_on = false; -+ int ret; - - if (pd->info->pwr_mask == 0) -- return; -+ return 0; - - if (on && pd->info->mem_status_mask) - is_mem_on = rockchip_pmu_domain_is_mem_on(pd); -@@ -557,16 +558,21 @@ static void rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *pd, - - wmb(); - -- if (is_mem_on && rockchip_pmu_domain_mem_reset(pd)) -- return; -+ if (is_mem_on) { -+ ret = rockchip_pmu_domain_mem_reset(pd); -+ if (ret) -+ return ret; -+ } - -- if (readx_poll_timeout_atomic(rockchip_pmu_domain_is_on, pd, is_on, -- is_on == on, 0, 10000)) { -- dev_err(pmu->dev, -- "failed to set domain '%s', val=%d\n", -- genpd->name, is_on); -- return; -+ ret = readx_poll_timeout_atomic(rockchip_pmu_domain_is_on, pd, is_on, -+ is_on == on, 0, 10000); -+ if (ret) { -+ dev_err(pmu->dev, "failed to set domain '%s' %s, val=%d\n", -+ genpd->name, on ? "on" : "off", is_on); -+ return ret; - } -+ -+ return 0; - } - - static int rockchip_pd_power(struct rockchip_pm_domain *pd, bool power_on) -@@ -592,7 +598,11 @@ static int rockchip_pd_power(struct rockchip_pm_domain *pd, bool power_on) - rockchip_pmu_set_idle_request(pd, true); - } - -- rockchip_do_pmu_set_power_domain(pd, power_on); -+ ret = rockchip_do_pmu_set_power_domain(pd, power_on); -+ if (ret < 0) { -+ clk_bulk_disable(pd->num_clks, pd->clks); -+ return ret; -+ } - - if (power_on) { - /* if powering up, leave idle mode */ --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0052-pmdomain-rockchip-reduce-indentation-in-rockchip_pd_.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0052-pmdomain-rockchip-reduce-indentation-in-rockchip_pd_.patch deleted file mode 100644 index 94e6cace49..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0052-pmdomain-rockchip-reduce-indentation-in-rockchip_pd_.patch +++ /dev/null @@ -1,91 +0,0 @@ -From f1e6adf952219bfe55b0bcbb18906f48187f4044 Mon Sep 17 00:00:00 2001 -From: Sebastian Reichel <sebastian.reichel@collabora.com> -Date: Fri, 6 Sep 2024 17:44:55 +0200 -Subject: [PATCH 52/63] pmdomain: rockchip: reduce indentation in - rockchip_pd_power - -Rework the logic, so that the function exits early when the -power domain state is already correct to reduce code indentation. - -No functional change intended. - -Reviewed-by: Heiko Stuebner <heiko@sntech.de> -Tested-by: Adrian Larumbe <adrian.larumbe@collabora.com> # On Rock 5B -Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> ---- - drivers/pmdomain/rockchip/pm-domains.c | 51 +++++++++++++------------- - 1 file changed, 26 insertions(+), 25 deletions(-) - -diff --git a/drivers/pmdomain/rockchip/pm-domains.c b/drivers/pmdomain/rockchip/pm-domains.c -index 8f440f2883db..f4e555dac20a 100644 ---- a/drivers/pmdomain/rockchip/pm-domains.c -+++ b/drivers/pmdomain/rockchip/pm-domains.c -@@ -582,39 +582,40 @@ static int rockchip_pd_power(struct rockchip_pm_domain *pd, bool power_on) - - guard(mutex)(&pmu->mutex); - -- if (rockchip_pmu_domain_is_on(pd) != power_on) { -- ret = clk_bulk_enable(pd->num_clks, pd->clks); -- if (ret < 0) { -- dev_err(pmu->dev, "failed to enable clocks\n"); -- return ret; -- } -+ if (rockchip_pmu_domain_is_on(pd) == power_on) -+ return 0; - -- rockchip_pmu_ungate_clk(pd, true); -+ ret = clk_bulk_enable(pd->num_clks, pd->clks); -+ if (ret < 0) { -+ dev_err(pmu->dev, "failed to enable clocks\n"); -+ return ret; -+ } - -- if (!power_on) { -- rockchip_pmu_save_qos(pd); -+ rockchip_pmu_ungate_clk(pd, true); - -- /* if powering down, idle request to NIU first */ -- rockchip_pmu_set_idle_request(pd, true); -- } -+ if (!power_on) { -+ rockchip_pmu_save_qos(pd); - -- ret = rockchip_do_pmu_set_power_domain(pd, power_on); -- if (ret < 0) { -- clk_bulk_disable(pd->num_clks, pd->clks); -- return ret; -- } -+ /* if powering down, idle request to NIU first */ -+ rockchip_pmu_set_idle_request(pd, true); -+ } - -- if (power_on) { -- /* if powering up, leave idle mode */ -- rockchip_pmu_set_idle_request(pd, false); -- -- rockchip_pmu_restore_qos(pd); -- } -- -- rockchip_pmu_ungate_clk(pd, false); -+ ret = rockchip_do_pmu_set_power_domain(pd, power_on); -+ if (ret < 0) { - clk_bulk_disable(pd->num_clks, pd->clks); -+ return ret; - } - -+ if (power_on) { -+ /* if powering up, leave idle mode */ -+ rockchip_pmu_set_idle_request(pd, false); -+ -+ rockchip_pmu_restore_qos(pd); -+ } -+ -+ rockchip_pmu_ungate_clk(pd, false); -+ clk_bulk_disable(pd->num_clks, pd->clks); -+ - return 0; - } - --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0053-dt-bindings-power-rockchip-add-regulator-support.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0053-dt-bindings-power-rockchip-add-regulator-support.patch deleted file mode 100644 index 5250be30a4..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0053-dt-bindings-power-rockchip-add-regulator-support.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 46564c268740e86caff8b63be101353518dfc001 Mon Sep 17 00:00:00 2001 -From: Sebastian Reichel <sebastian.reichel@collabora.com> -Date: Fri, 6 Sep 2024 19:15:24 +0200 -Subject: [PATCH 53/63] dt-bindings: power: rockchip: add regulator support - -Add optional support for a voltage supply required to enable a -power domain. The binding follows the way it is handled by the -Mediatek binding to keep things consistent. - -This will initially be used by the RK3588 GPU power domain, which -fails to be enabled when the GPU regulator is not enabled. It is -not limited to that platform, since older generations have similar -requirements. They worked around this by marking the regulators -as always-on instead of describing the dependency. - -Reviewed-by: Heiko Stuebner <heiko@sntech.de> -Acked-by: Rob Herring (Arm) <robh@kernel.org> -Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> ---- - .../devicetree/bindings/power/rockchip,power-controller.yaml | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/Documentation/devicetree/bindings/power/rockchip,power-controller.yaml b/Documentation/devicetree/bindings/power/rockchip,power-controller.yaml -index 650dc0aae6f5..ebab98987e49 100644 ---- a/Documentation/devicetree/bindings/power/rockchip,power-controller.yaml -+++ b/Documentation/devicetree/bindings/power/rockchip,power-controller.yaml -@@ -132,6 +132,9 @@ $defs: - A number of phandles to clocks that need to be enabled - while power domain switches state. - -+ domain-supply: -+ description: domain regulator supply. -+ - pm_qos: - $ref: /schemas/types.yaml#/definitions/phandle-array - items: --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0054-pmdomain-rockchip-add-regulator-support.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0054-pmdomain-rockchip-add-regulator-support.patch deleted file mode 100644 index 2833172ad9..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0054-pmdomain-rockchip-add-regulator-support.patch +++ /dev/null @@ -1,222 +0,0 @@ -From bdd2203114aaa9da7bf9f6010b69abad051e9030 Mon Sep 17 00:00:00 2001 -From: Sebastian Reichel <sebastian.reichel@collabora.com> -Date: Fri, 6 Sep 2024 18:40:51 +0200 -Subject: [PATCH 54/63] pmdomain: rockchip: add regulator support - -Some power domains require extra voltages to be applied. For example -trying to enable the GPU power domain on RK3588 fails when the SoC -does not have VDD GPU enabled. The same is expected to happen for -the NPU, which also has a dedicated supply line. - -We get the regulator using devm_of_regulator_get(), so a missing -dependency in the devicetree is handled gracefully by printing a warning -and creating a dummy regulator. This is necessary, since existing DTs do -not have the regulator described. They might still work if the regulator -is marked as always-on. It is also working if the regulator is enabled -at boot time and the GPU driver is probed before the kernel disables -unused regulators. - -The regulator itself is not acquired at driver probe time, since that -creates an unsolvable circular dependency. The power domain driver must -be probed early, since SoC peripherals need it. Regulators on the other -hand depend on SoC peripherals like SPI, I2C or GPIO. MediaTek does not -run into this, since they have two power domain drivers. - -Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> ---- - drivers/pmdomain/rockchip/pm-domains.c | 113 +++++++++++++++++-------- - 1 file changed, 79 insertions(+), 34 deletions(-) - -diff --git a/drivers/pmdomain/rockchip/pm-domains.c b/drivers/pmdomain/rockchip/pm-domains.c -index f4e555dac20a..31c71b6fddf1 100644 ---- a/drivers/pmdomain/rockchip/pm-domains.c -+++ b/drivers/pmdomain/rockchip/pm-domains.c -@@ -18,6 +18,7 @@ - #include <linux/of_clk.h> - #include <linux/clk.h> - #include <linux/regmap.h> -+#include <linux/regulator/consumer.h> - #include <linux/mfd/syscon.h> - #include <soc/rockchip/pm_domains.h> - #include <dt-bindings/power/px30-power.h> -@@ -44,6 +45,7 @@ struct rockchip_domain_info { - int idle_mask; - int ack_mask; - bool active_wakeup; -+ bool need_regulator; - int pwr_w_mask; - int req_w_mask; - int clk_ungate_mask; -@@ -92,6 +94,8 @@ struct rockchip_pm_domain { - u32 *qos_save_regs[MAX_QOS_REGS_NUM]; - int num_clks; - struct clk_bulk_data *clks; -+ struct device_node *node; -+ struct regulator *supply; - }; - - struct rockchip_pmu { -@@ -129,7 +133,7 @@ struct rockchip_pmu { - .active_wakeup = wakeup, \ - } - --#define DOMAIN_M_O_R(_name, p_offset, pwr, status, m_offset, m_status, r_status, r_offset, req, idle, ack, wakeup) \ -+#define DOMAIN_M_O_R(_name, p_offset, pwr, status, m_offset, m_status, r_status, r_offset, req, idle, ack, wakeup, regulator) \ - { \ - .name = _name, \ - .pwr_offset = p_offset, \ -@@ -145,6 +149,7 @@ struct rockchip_pmu { - .idle_mask = (idle), \ - .ack_mask = (ack), \ - .active_wakeup = wakeup, \ -+ .need_regulator = regulator, \ - } - - #define DOMAIN_M_O_R_G(_name, p_offset, pwr, status, m_offset, m_status, r_status, r_offset, req, idle, ack, g_mask, wakeup) \ -@@ -303,8 +308,8 @@ void rockchip_pmu_unblock(void) - } - EXPORT_SYMBOL_GPL(rockchip_pmu_unblock); - --#define DOMAIN_RK3588(name, p_offset, pwr, status, m_offset, m_status, r_status, r_offset, req, idle, wakeup) \ -- DOMAIN_M_O_R(name, p_offset, pwr, status, m_offset, m_status, r_status, r_offset, req, idle, idle, wakeup) -+#define DOMAIN_RK3588(name, p_offset, pwr, status, m_offset, m_status, r_status, r_offset, req, idle, wakeup, regulator) \ -+ DOMAIN_M_O_R(name, p_offset, pwr, status, m_offset, m_status, r_status, r_offset, req, idle, idle, wakeup, regulator) - - static bool rockchip_pmu_domain_is_idle(struct rockchip_pm_domain *pd) - { -@@ -619,18 +624,57 @@ static int rockchip_pd_power(struct rockchip_pm_domain *pd, bool power_on) - return 0; - } - -+static int rockchip_pd_regulator_disable(struct rockchip_pm_domain *pd) -+{ -+ return IS_ERR_OR_NULL(pd->supply) ? 0 : regulator_disable(pd->supply); -+} -+ -+static int rockchip_pd_regulator_enable(struct rockchip_pm_domain *pd) -+{ -+ struct rockchip_pmu *pmu = pd->pmu; -+ -+ if (!pd->info->need_regulator) -+ return 0; -+ -+ if (IS_ERR_OR_NULL(pd->supply)) { -+ pd->supply = devm_of_regulator_get(pmu->dev, pd->node, "domain"); -+ -+ if (IS_ERR(pd->supply)) -+ return PTR_ERR(pd->supply); -+ } -+ -+ return regulator_enable(pd->supply); -+} -+ - static int rockchip_pd_power_on(struct generic_pm_domain *domain) - { - struct rockchip_pm_domain *pd = to_rockchip_pd(domain); -+ int ret; - -- return rockchip_pd_power(pd, true); -+ ret = rockchip_pd_regulator_enable(pd); -+ if (ret) { -+ dev_err(pd->pmu->dev, "Failed to enable supply: %d\n", ret); -+ return ret; -+ } -+ -+ ret = rockchip_pd_power(pd, true); -+ if (ret) -+ rockchip_pd_regulator_disable(pd); -+ -+ return ret; - } - - static int rockchip_pd_power_off(struct generic_pm_domain *domain) - { - struct rockchip_pm_domain *pd = to_rockchip_pd(domain); -+ int ret; - -- return rockchip_pd_power(pd, false); -+ ret = rockchip_pd_power(pd, false); -+ if (ret) -+ return ret; -+ -+ rockchip_pd_regulator_disable(pd); -+ return ret; - } - - static int rockchip_pd_attach_dev(struct generic_pm_domain *genpd, -@@ -711,6 +755,7 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu, - - pd->info = pd_info; - pd->pmu = pmu; -+ pd->node = node; - - pd->num_clks = of_clk_get_parent_count(node); - if (pd->num_clks > 0) { -@@ -1174,35 +1219,35 @@ static const struct rockchip_domain_info rk3576_pm_domains[] = { - }; - - static const struct rockchip_domain_info rk3588_pm_domains[] = { -- [RK3588_PD_GPU] = DOMAIN_RK3588("gpu", 0x0, BIT(0), 0, 0x0, 0, BIT(1), 0x0, BIT(0), BIT(0), false), -- [RK3588_PD_NPU] = DOMAIN_RK3588("npu", 0x0, BIT(1), BIT(1), 0x0, 0, 0, 0x0, 0, 0, false), -- [RK3588_PD_VCODEC] = DOMAIN_RK3588("vcodec", 0x0, BIT(2), BIT(2), 0x0, 0, 0, 0x0, 0, 0, false), -- [RK3588_PD_NPUTOP] = DOMAIN_RK3588("nputop", 0x0, BIT(3), 0, 0x0, BIT(11), BIT(2), 0x0, BIT(1), BIT(1), false), -- [RK3588_PD_NPU1] = DOMAIN_RK3588("npu1", 0x0, BIT(4), 0, 0x0, BIT(12), BIT(3), 0x0, BIT(2), BIT(2), false), -- [RK3588_PD_NPU2] = DOMAIN_RK3588("npu2", 0x0, BIT(5), 0, 0x0, BIT(13), BIT(4), 0x0, BIT(3), BIT(3), false), -- [RK3588_PD_VENC0] = DOMAIN_RK3588("venc0", 0x0, BIT(6), 0, 0x0, BIT(14), BIT(5), 0x0, BIT(4), BIT(4), false), -- [RK3588_PD_VENC1] = DOMAIN_RK3588("venc1", 0x0, BIT(7), 0, 0x0, BIT(15), BIT(6), 0x0, BIT(5), BIT(5), false), -- [RK3588_PD_RKVDEC0] = DOMAIN_RK3588("rkvdec0", 0x0, BIT(8), 0, 0x0, BIT(16), BIT(7), 0x0, BIT(6), BIT(6), false), -- [RK3588_PD_RKVDEC1] = DOMAIN_RK3588("rkvdec1", 0x0, BIT(9), 0, 0x0, BIT(17), BIT(8), 0x0, BIT(7), BIT(7), false), -- [RK3588_PD_VDPU] = DOMAIN_RK3588("vdpu", 0x0, BIT(10), 0, 0x0, BIT(18), BIT(9), 0x0, BIT(8), BIT(8), false), -- [RK3588_PD_RGA30] = DOMAIN_RK3588("rga30", 0x0, BIT(11), 0, 0x0, BIT(19), BIT(10), 0x0, 0, 0, false), -- [RK3588_PD_AV1] = DOMAIN_RK3588("av1", 0x0, BIT(12), 0, 0x0, BIT(20), BIT(11), 0x0, BIT(9), BIT(9), false), -- [RK3588_PD_VI] = DOMAIN_RK3588("vi", 0x0, BIT(13), 0, 0x0, BIT(21), BIT(12), 0x0, BIT(10), BIT(10), false), -- [RK3588_PD_FEC] = DOMAIN_RK3588("fec", 0x0, BIT(14), 0, 0x0, BIT(22), BIT(13), 0x0, 0, 0, false), -- [RK3588_PD_ISP1] = DOMAIN_RK3588("isp1", 0x0, BIT(15), 0, 0x0, BIT(23), BIT(14), 0x0, BIT(11), BIT(11), false), -- [RK3588_PD_RGA31] = DOMAIN_RK3588("rga31", 0x4, BIT(0), 0, 0x0, BIT(24), BIT(15), 0x0, BIT(12), BIT(12), false), -- [RK3588_PD_VOP] = DOMAIN_RK3588("vop", 0x4, BIT(1), 0, 0x0, BIT(25), BIT(16), 0x0, BIT(13) | BIT(14), BIT(13) | BIT(14), false), -- [RK3588_PD_VO0] = DOMAIN_RK3588("vo0", 0x4, BIT(2), 0, 0x0, BIT(26), BIT(17), 0x0, BIT(15), BIT(15), false), -- [RK3588_PD_VO1] = DOMAIN_RK3588("vo1", 0x4, BIT(3), 0, 0x0, BIT(27), BIT(18), 0x4, BIT(0), BIT(16), false), -- [RK3588_PD_AUDIO] = DOMAIN_RK3588("audio", 0x4, BIT(4), 0, 0x0, BIT(28), BIT(19), 0x4, BIT(1), BIT(17), false), -- [RK3588_PD_PHP] = DOMAIN_RK3588("php", 0x4, BIT(5), 0, 0x0, BIT(29), BIT(20), 0x4, BIT(5), BIT(21), false), -- [RK3588_PD_GMAC] = DOMAIN_RK3588("gmac", 0x4, BIT(6), 0, 0x0, BIT(30), BIT(21), 0x0, 0, 0, false), -- [RK3588_PD_PCIE] = DOMAIN_RK3588("pcie", 0x4, BIT(7), 0, 0x0, BIT(31), BIT(22), 0x0, 0, 0, true), -- [RK3588_PD_NVM] = DOMAIN_RK3588("nvm", 0x4, BIT(8), BIT(24), 0x4, 0, 0, 0x4, BIT(2), BIT(18), false), -- [RK3588_PD_NVM0] = DOMAIN_RK3588("nvm0", 0x4, BIT(9), 0, 0x4, BIT(1), BIT(23), 0x0, 0, 0, false), -- [RK3588_PD_SDIO] = DOMAIN_RK3588("sdio", 0x4, BIT(10), 0, 0x4, BIT(2), BIT(24), 0x4, BIT(3), BIT(19), false), -- [RK3588_PD_USB] = DOMAIN_RK3588("usb", 0x4, BIT(11), 0, 0x4, BIT(3), BIT(25), 0x4, BIT(4), BIT(20), true), -- [RK3588_PD_SDMMC] = DOMAIN_RK3588("sdmmc", 0x4, BIT(13), 0, 0x4, BIT(5), BIT(26), 0x0, 0, 0, false), -+ [RK3588_PD_GPU] = DOMAIN_RK3588("gpu", 0x0, BIT(0), 0, 0x0, 0, BIT(1), 0x0, BIT(0), BIT(0), false, true), -+ [RK3588_PD_NPU] = DOMAIN_RK3588("npu", 0x0, BIT(1), BIT(1), 0x0, 0, 0, 0x0, 0, 0, false, true), -+ [RK3588_PD_VCODEC] = DOMAIN_RK3588("vcodec", 0x0, BIT(2), BIT(2), 0x0, 0, 0, 0x0, 0, 0, false, false), -+ [RK3588_PD_NPUTOP] = DOMAIN_RK3588("nputop", 0x0, BIT(3), 0, 0x0, BIT(11), BIT(2), 0x0, BIT(1), BIT(1), false, false), -+ [RK3588_PD_NPU1] = DOMAIN_RK3588("npu1", 0x0, BIT(4), 0, 0x0, BIT(12), BIT(3), 0x0, BIT(2), BIT(2), false, false), -+ [RK3588_PD_NPU2] = DOMAIN_RK3588("npu2", 0x0, BIT(5), 0, 0x0, BIT(13), BIT(4), 0x0, BIT(3), BIT(3), false, false), -+ [RK3588_PD_VENC0] = DOMAIN_RK3588("venc0", 0x0, BIT(6), 0, 0x0, BIT(14), BIT(5), 0x0, BIT(4), BIT(4), false, false), -+ [RK3588_PD_VENC1] = DOMAIN_RK3588("venc1", 0x0, BIT(7), 0, 0x0, BIT(15), BIT(6), 0x0, BIT(5), BIT(5), false, false), -+ [RK3588_PD_RKVDEC0] = DOMAIN_RK3588("rkvdec0", 0x0, BIT(8), 0, 0x0, BIT(16), BIT(7), 0x0, BIT(6), BIT(6), false, false), -+ [RK3588_PD_RKVDEC1] = DOMAIN_RK3588("rkvdec1", 0x0, BIT(9), 0, 0x0, BIT(17), BIT(8), 0x0, BIT(7), BIT(7), false, false), -+ [RK3588_PD_VDPU] = DOMAIN_RK3588("vdpu", 0x0, BIT(10), 0, 0x0, BIT(18), BIT(9), 0x0, BIT(8), BIT(8), false, false), -+ [RK3588_PD_RGA30] = DOMAIN_RK3588("rga30", 0x0, BIT(11), 0, 0x0, BIT(19), BIT(10), 0x0, 0, 0, false, false), -+ [RK3588_PD_AV1] = DOMAIN_RK3588("av1", 0x0, BIT(12), 0, 0x0, BIT(20), BIT(11), 0x0, BIT(9), BIT(9), false, false), -+ [RK3588_PD_VI] = DOMAIN_RK3588("vi", 0x0, BIT(13), 0, 0x0, BIT(21), BIT(12), 0x0, BIT(10), BIT(10), false, false), -+ [RK3588_PD_FEC] = DOMAIN_RK3588("fec", 0x0, BIT(14), 0, 0x0, BIT(22), BIT(13), 0x0, 0, 0, false, false), -+ [RK3588_PD_ISP1] = DOMAIN_RK3588("isp1", 0x0, BIT(15), 0, 0x0, BIT(23), BIT(14), 0x0, BIT(11), BIT(11), false, false), -+ [RK3588_PD_RGA31] = DOMAIN_RK3588("rga31", 0x4, BIT(0), 0, 0x0, BIT(24), BIT(15), 0x0, BIT(12), BIT(12), false, false), -+ [RK3588_PD_VOP] = DOMAIN_RK3588("vop", 0x4, BIT(1), 0, 0x0, BIT(25), BIT(16), 0x0, BIT(13) | BIT(14), BIT(13) | BIT(14), false, false), -+ [RK3588_PD_VO0] = DOMAIN_RK3588("vo0", 0x4, BIT(2), 0, 0x0, BIT(26), BIT(17), 0x0, BIT(15), BIT(15), false, false), -+ [RK3588_PD_VO1] = DOMAIN_RK3588("vo1", 0x4, BIT(3), 0, 0x0, BIT(27), BIT(18), 0x4, BIT(0), BIT(16), false, false), -+ [RK3588_PD_AUDIO] = DOMAIN_RK3588("audio", 0x4, BIT(4), 0, 0x0, BIT(28), BIT(19), 0x4, BIT(1), BIT(17), false, false), -+ [RK3588_PD_PHP] = DOMAIN_RK3588("php", 0x4, BIT(5), 0, 0x0, BIT(29), BIT(20), 0x4, BIT(5), BIT(21), false, false), -+ [RK3588_PD_GMAC] = DOMAIN_RK3588("gmac", 0x4, BIT(6), 0, 0x0, BIT(30), BIT(21), 0x0, 0, 0, false, false), -+ [RK3588_PD_PCIE] = DOMAIN_RK3588("pcie", 0x4, BIT(7), 0, 0x0, BIT(31), BIT(22), 0x0, 0, 0, true, false), -+ [RK3588_PD_NVM] = DOMAIN_RK3588("nvm", 0x4, BIT(8), BIT(24), 0x4, 0, 0, 0x4, BIT(2), BIT(18), false, false), -+ [RK3588_PD_NVM0] = DOMAIN_RK3588("nvm0", 0x4, BIT(9), 0, 0x4, BIT(1), BIT(23), 0x0, 0, 0, false, false), -+ [RK3588_PD_SDIO] = DOMAIN_RK3588("sdio", 0x4, BIT(10), 0, 0x4, BIT(2), BIT(24), 0x4, BIT(3), BIT(19), false, false), -+ [RK3588_PD_USB] = DOMAIN_RK3588("usb", 0x4, BIT(11), 0, 0x4, BIT(3), BIT(25), 0x4, BIT(4), BIT(20), true, false), -+ [RK3588_PD_SDMMC] = DOMAIN_RK3588("sdmmc", 0x4, BIT(13), 0, 0x4, BIT(5), BIT(26), 0x0, 0, 0, false, false), - }; - - static const struct rockchip_pmu_info px30_pmu = { --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0055-arm64-dts-rockchip-Add-GPU-power-domain-regulator-de.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0055-arm64-dts-rockchip-Add-GPU-power-domain-regulator-de.patch deleted file mode 100644 index c7a1cdacc7..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0055-arm64-dts-rockchip-Add-GPU-power-domain-regulator-de.patch +++ /dev/null @@ -1,426 +0,0 @@ -From ca97aa217e5cc8d617d677c48ca7eeac69e9e18d Mon Sep 17 00:00:00 2001 -From: Sebastian Reichel <sebastian.reichel@collabora.com> -Date: Fri, 6 Sep 2024 19:24:03 +0200 -Subject: [PATCH 55/63] arm64: dts: rockchip: Add GPU power domain regulator - dependency for RK3588 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Enabling the GPU power domain requires that the GPU regulator is -enabled. The regulator is enabled at boot time, but automatically -gets disabled when there are no users. - -If the GPU driver is not probed at boot time or rebound while -the system is running the system will try to enable the power -domain before the regulator is enabled resulting in a failure -hanging the whole system. Avoid this by adding an explicit -dependency. - -Reported-by: Adrián Martínez Larumbe <adrian.larumbe@collabora.com> -Tested-by: Adrian Larumbe <adrian.larumbe@collabora.com> # On Rock 5B -Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> ---- - arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts | 4 ++++ - arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 2 +- - arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5.dtsi | 4 ++++ - arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-common.dtsi | 4 ++++ - arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts | 4 ++++ - arch/arm64/boot/dts/rockchip/rk3588-fet3588-c.dtsi | 4 ++++ - arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588.dtsi | 4 ++++ - arch/arm64/boot/dts/rockchip/rk3588-jaguar.dts | 4 ++++ - arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi | 4 ++++ - arch/arm64/boot/dts/rockchip/rk3588-ok3588-c.dts | 4 ++++ - arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts | 4 ++++ - arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts | 4 ++++ - arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts | 4 ++++ - arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 4 ++++ - arch/arm64/boot/dts/rockchip/rk3588-tiger.dtsi | 4 ++++ - arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts | 4 ++++ - arch/arm64/boot/dts/rockchip/rk3588-turing-rk1.dtsi | 4 ++++ - arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts | 4 ++++ - arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts | 4 ++++ - arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts | 4 ++++ - arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts | 4 ++++ - arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6s.dts | 4 ++++ - arch/arm64/boot/dts/rockchip/rk3588s-odroid-m2.dts | 4 ++++ - arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts | 4 ++++ - arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 4 ++++ - 25 files changed, 97 insertions(+), 1 deletion(-) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts b/arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts -index c667704ba985..00a1cd96781d 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts -@@ -286,6 +286,10 @@ &pcie3x4 { - status = "okay"; - }; - -+&pd_gpu { -+ domain-supply = <&vdd_gpu_s0>; -+}; -+ - &pinctrl { - hym8563 { - hym8563_int: hym8563-int { -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi -index ab07e3deff69..81e0e4dd8c3d 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi -@@ -865,7 +865,7 @@ power-domain@RK3588_PD_NPU2 { - }; - }; - /* These power domains are grouped by VD_GPU */ -- power-domain@RK3588_PD_GPU { -+ pd_gpu: power-domain@RK3588_PD_GPU { - reg = <RK3588_PD_GPU>; - clocks = <&cru CLK_GPU>, - <&cru CLK_GPU_COREGROUP>, -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5.dtsi -index fde8b228f2c7..cf9d75159ba6 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5.dtsi -@@ -277,6 +277,10 @@ &pcie2x1l2 { - status = "okay"; - }; - -+&pd_gpu { -+ domain-supply = <&vdd_gpu_s0>; -+}; -+ - &pinctrl { - hym8563 { - hym8563_int: hym8563-int { -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-common.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-common.dtsi -index 03fd193be253..381242c8d6db 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-common.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-common.dtsi -@@ -126,6 +126,10 @@ regulator-state-mem { - }; - }; - -+&pd_gpu { -+ domain-supply = <&vdd_gpu_s0>; -+}; -+ - &pinctrl { - leds { - led_user_en: led_user_en { -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts -index 7dc3ee6e7eb4..142e685ae513 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts -@@ -485,6 +485,10 @@ &pcie3x4 { - status = "okay"; - }; - -+&pd_gpu { -+ domain-supply = <&vdd_gpu_s0>; -+}; -+ - &pinctrl { - audio { - hp_detect: headphone-detect { -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-fet3588-c.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-fet3588-c.dtsi -index 47e64d547ea9..799a71da7157 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-fet3588-c.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3588-fet3588-c.dtsi -@@ -205,6 +205,10 @@ regulator-state-mem { - }; - }; - -+&pd_gpu { -+ domain-supply = <&vdd_gpu_s0>; -+}; -+ - &pinctrl { - leds { - led_rgb_b: led-rgb-b { -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588.dtsi -index e3a9598b99fc..1af0a30866f6 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588.dtsi -@@ -256,6 +256,10 @@ &pcie2x1l2 { - status = "okay"; - }; - -+&pd_gpu { -+ domain-supply = <&vdd_gpu_s0>; -+}; -+ - &pinctrl { - gpio-leds { - led_sys_pin: led-sys-pin { -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-jaguar.dts b/arch/arm64/boot/dts/rockchip/rk3588-jaguar.dts -index 31d2f8994f85..3cefaf830229 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-jaguar.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3588-jaguar.dts -@@ -403,6 +403,10 @@ &pcie3x4 { - status = "okay"; - }; - -+&pd_gpu { -+ domain-supply = <&vdd_gpu_s0>; -+}; -+ - &pinctrl { - emmc { - emmc_reset: emmc-reset { -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi -index fc131789b4c3..30a5e4e9e844 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi -@@ -519,6 +519,10 @@ &pcie3x4 { - status = "okay"; - }; - -+&pd_gpu { -+ domain-supply = <&vdd_gpu_s0>; -+}; -+ - &pinctrl { - gpio-leds { - sys_led_pin: sys-led-pin { -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-ok3588-c.dts b/arch/arm64/boot/dts/rockchip/rk3588-ok3588-c.dts -index c2a08bdf09e8..a9c1fed929fd 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-ok3588-c.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3588-ok3588-c.dts -@@ -312,6 +312,10 @@ &pcie3x4 { - status = "okay"; - }; - -+&pd_gpu { -+ domain-supply = <&vdd_gpu_s0>; -+}; -+ - &pinctrl { - pcie2 { - pcie2_0_rst: pcie2-0-rst { -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts b/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts -index dd4c79bcad87..b6ce6cb233f3 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts -@@ -388,6 +388,10 @@ &pcie3x4 { - status = "okay"; - }; - -+&pd_gpu { -+ domain-supply = <&vdd_gpu_s0>; -+}; -+ - &pinctrl { - hym8563 { - hym8563_int: hym8563-int { -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts b/arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts -index b38dab009ccc..1f5676be768f 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts -@@ -347,6 +347,10 @@ rgmii_phy: ethernet-phy@1 { - }; - }; - -+&pd_gpu { -+ domain-supply = <&vdd_gpu_s0>; -+}; -+ - &pinctrl { - hym8563 { - hym8563_int: hym8563-int { -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts -index d0b922b8d67e..0eadf4fb4ba4 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts -@@ -530,6 +530,10 @@ &pcie3x4 { - status = "okay"; - }; - -+&pd_gpu { -+ domain-supply = <&vdd_gpu_s0>; -+}; -+ - &pinctrl { - hym8563 { - rtc_int: rtc-int { -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts -index 903066a23757..101e71d8cc9e 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts -@@ -465,6 +465,10 @@ &pcie3x4 { - status = "okay"; - }; - -+&pd_gpu { -+ domain-supply = <&vdd_gpu_s0>; -+}; -+ - &pinctrl { - hdmirx { - hdmirx_hpd: hdmirx-5v-detection { -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-tiger.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-tiger.dtsi -index 615094bb8ba3..1b5c4a7fd5c6 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-tiger.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3588-tiger.dtsi -@@ -317,6 +317,10 @@ &pcie3x4 { - reset-gpios = <&gpio3 RK_PB6 GPIO_ACTIVE_HIGH>; - }; - -+&pd_gpu { -+ domain-supply = <&vdd_gpu_s0>; -+}; -+ - &pinctrl { - emmc { - emmc_reset: emmc-reset { -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts b/arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts -index 328dcb894ccb..7558e3663c8a 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts -@@ -289,6 +289,10 @@ rgmii_phy: ethernet-phy@1 { - }; - }; - -+&pd_gpu { -+ domain-supply = <&vdd_gpu_s0>; -+}; -+ - &pinctrl { - rtl8211f { - rtl8211f_rst: rtl8211f-rst { -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-turing-rk1.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-turing-rk1.dtsi -index 432133251e31..f98c7ed422a2 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-turing-rk1.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3588-turing-rk1.dtsi -@@ -229,6 +229,10 @@ &pcie3x4 { - status = "okay"; - }; - -+&pd_gpu { -+ domain-supply = <&vdd_gpu_s0>; -+}; -+ - &pinctrl { - fan { - fan_int: fan-int { -diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts b/arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts -index 074c316a9a69..d938db0e2239 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts -@@ -329,6 +329,10 @@ &pcie2x1l2 { - status = "okay"; - }; - -+&pd_gpu { -+ domain-supply = <&vdd_gpu_s0>; -+}; -+ - &pinctrl { - hym8563 { - hym8563_int: hym8563-int { -diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts b/arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts -index 467f69594089..9b02cea96cdb 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts -@@ -675,6 +675,10 @@ &pcie2x1l1 { - status = "okay"; - }; - -+&pd_gpu { -+ domain-supply = <&vdd_gpu_s0>; -+}; -+ - &pinctrl { - audio-amplifier { - headphone_amplifier_en: headphone-amplifier-en { -diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts -index 8ba111d9283f..817c0bb28b6e 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts -@@ -415,6 +415,10 @@ &pcie2x1l2 { - status = "okay"; - }; - -+&pd_gpu { -+ domain-supply = <&vdd_gpu_s0>; -+}; -+ - &pinctrl { - bluetooth-pins { - bt_reset: bt-reset { -diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts -index dbddfc3bb464..d29d404417ee 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts -@@ -233,6 +233,10 @@ hym8563: rtc@51 { - }; - }; - -+&pd_gpu { -+ domain-supply = <&vdd_gpu_s0>; -+}; -+ - &pinctrl { - vdd_sd { - vdd_sd_en: vdd-sd-en { -diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6s.dts b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6s.dts -index 4fa644ae510c..3dd8372b2578 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6s.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6s.dts -@@ -326,6 +326,10 @@ &pcie2x1l2 { - status = "okay"; - }; - -+&pd_gpu { -+ domain-supply = <&vdd_gpu_s0>; -+}; -+ - &pinctrl { - gpio-key { - key1_pin: key1-pin { -diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-odroid-m2.dts b/arch/arm64/boot/dts/rockchip/rk3588s-odroid-m2.dts -index 63d91236ba9f..5f32a339f5c9 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588s-odroid-m2.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3588s-odroid-m2.dts -@@ -401,6 +401,10 @@ &pcie2x1l2 { - status = "okay"; - }; - -+&pd_gpu { -+ domain-supply = <&vdd_gpu_s0>; -+}; -+ - &pinctrl { - lcd { - lcd_pwren: lcd-pwren { -diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts b/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts -index feea6b20a6bf..ef3a721d1fc7 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts -@@ -297,6 +297,10 @@ &pcie2x1l2 { - status = "okay"; - }; - -+&pd_gpu { -+ domain-supply = <&vdd_gpu_s0>; -+}; -+ - &pinctrl { - gpio-func { - leds_gpio: leds-gpio { -diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts -index 294b99dd50da..a61864482f1f 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts -@@ -317,6 +317,10 @@ &pcie2x1l2 { - status = "okay"; - }; - -+&pd_gpu { -+ domain-supply = <&vdd_gpu_s0>; -+}; -+ - &pinctrl { - leds { - io_led: io-led { --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0056-dt-bindings-net-wireless-brcm4329-fmac-add-pci14e4-4.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0056-dt-bindings-net-wireless-brcm4329-fmac-add-pci14e4-4.patch deleted file mode 100644 index 79937824a3..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0056-dt-bindings-net-wireless-brcm4329-fmac-add-pci14e4-4.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 772226d5ed2afbcfadd24f4b8f1ea9f9ae0fd03b Mon Sep 17 00:00:00 2001 -From: Jacobe Zang <jacobe.zang@wesion.com> -Date: Tue, 10 Sep 2024 11:04:11 +0800 -Subject: [PATCH 56/63] dt-bindings: net: wireless: brcm4329-fmac: add - pci14e4,449d - -It's the device id used by AP6275P which is the Wi-Fi module -used by Rockchip's RK3588 evaluation board and also used in -some other RK3588 boards. - -Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com> -Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> -Signed-off-by: Jacobe Zang <jacobe.zang@wesion.com> -Link: https://lore.kernel.org/r/20240910-wireless-mainline-v14-1-9d80fea5326d@wesion.com -Signed-off-by: Sebastian Reichel <sre@kernel.org> ---- - .../devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml b/Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml -index e564f20d8f41..2c2093c77ec9 100644 ---- a/Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml -+++ b/Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml -@@ -53,6 +53,7 @@ properties: - - pci14e4,4488 # BCM4377 - - pci14e4,4425 # BCM4378 - - pci14e4,4433 # BCM4387 -+ - pci14e4,449d # BCM43752 - - reg: - description: SDIO function number for the device (for most cases --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0057-dt-bindings-net-wireless-brcm4329-fmac-add-clock-des.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0057-dt-bindings-net-wireless-brcm4329-fmac-add-clock-des.patch deleted file mode 100644 index df1890a7f4..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0057-dt-bindings-net-wireless-brcm4329-fmac-add-clock-des.patch +++ /dev/null @@ -1,41 +0,0 @@ -From ae858097006e853d26bc6199244d740fd0aefe4e Mon Sep 17 00:00:00 2001 -From: Jacobe Zang <jacobe.zang@wesion.com> -Date: Tue, 10 Sep 2024 11:04:12 +0800 -Subject: [PATCH 57/63] dt-bindings: net: wireless: brcm4329-fmac: add clock - description for AP6275P - -Not only AP6275P Wi-Fi device but also all Broadcom wireless devices allow -external low power clock input. In DTS the clock as an optional choice in -the absence of an internal clock. - -Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com> -Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> -Signed-off-by: Jacobe Zang <jacobe.zang@wesion.com> -Link: https://lore.kernel.org/r/20240910-wireless-mainline-v14-2-9d80fea5326d@wesion.com -Signed-off-by: Sebastian Reichel <sre@kernel.org> ---- - .../bindings/net/wireless/brcm,bcm4329-fmac.yaml | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml b/Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml -index 2c2093c77ec9..a3607d55ef36 100644 ---- a/Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml -+++ b/Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml -@@ -122,6 +122,14 @@ properties: - NVRAM. This would normally be filled in by the bootloader from platform - configuration data. - -+ clocks: -+ items: -+ - description: External Low Power Clock input (32.768KHz) -+ -+ clock-names: -+ items: -+ - const: lpo -+ - required: - - compatible - - reg --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0058-wifi-brcmfmac-Add-optional-lpo-clock-enable-support.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0058-wifi-brcmfmac-Add-optional-lpo-clock-enable-support.patch deleted file mode 100644 index c0f3fd2fd0..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0058-wifi-brcmfmac-Add-optional-lpo-clock-enable-support.patch +++ /dev/null @@ -1,286 +0,0 @@ -From 834e7c313c8f1134101427d74f845c39e3f8a901 Mon Sep 17 00:00:00 2001 -From: Jacobe Zang <jacobe.zang@wesion.com> -Date: Tue, 10 Sep 2024 11:04:13 +0800 -Subject: [PATCH 58/63] wifi: brcmfmac: Add optional lpo clock enable support - -WiFi modules often require 32kHz clock to function. Add support to -enable the clock to PCIe driver and move "brcm,bcm4329-fmac" check -to the top of brcmf_of_probe. Change function prototypes from void -to int and add appropriate errno's for return values that will be -send to bus when error occurred. - -Co-developed-by: Ondrej Jirman <megi@xff.cz> -Signed-off-by: Ondrej Jirman <megi@xff.cz> -Co-developed-by: Arend van Spriel <arend.vanspriel@broadcom.com> -Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> -Reviewed-by: Sai Krishna <saikrishnag@marvell.com> -Signed-off-by: Jacobe Zang <jacobe.zang@wesion.com> -Link: https://lore.kernel.org/r/20240910-wireless-mainline-v14-3-9d80fea5326d@wesion.com -Signed-off-by: Sebastian Reichel <sre@kernel.org> ---- - .../broadcom/brcm80211/brcmfmac/bcmsdh.c | 4 +-- - .../broadcom/brcm80211/brcmfmac/common.c | 3 ++- - .../wireless/broadcom/brcm80211/brcmfmac/of.c | 25 +++++++++++++------ - .../wireless/broadcom/brcm80211/brcmfmac/of.h | 9 ++++--- - .../broadcom/brcm80211/brcmfmac/pcie.c | 3 +++ - .../broadcom/brcm80211/brcmfmac/sdio.c | 22 ++++++++++------ - .../broadcom/brcm80211/brcmfmac/usb.c | 3 +++ - 7 files changed, 47 insertions(+), 22 deletions(-) - -diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c -index d35262335eaf..17f6b33beabd 100644 ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c -@@ -947,8 +947,8 @@ int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev) - - /* try to attach to the target device */ - sdiodev->bus = brcmf_sdio_probe(sdiodev); -- if (!sdiodev->bus) { -- ret = -ENODEV; -+ if (IS_ERR(sdiodev->bus)) { -+ ret = PTR_ERR(sdiodev->bus); - goto out; - } - brcmf_sdiod_host_fixup(sdiodev->func2->card->host); -diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c -index b24faae35873..58d50918dd17 100644 ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c -@@ -561,7 +561,8 @@ struct brcmf_mp_device *brcmf_get_module_param(struct device *dev, - if (!found) { - /* No platform data for this device, try OF and DMI data */ - brcmf_dmi_probe(settings, chip, chiprev); -- brcmf_of_probe(dev, bus_type, settings); -+ if (brcmf_of_probe(dev, bus_type, settings) == -EPROBE_DEFER) -+ return ERR_PTR(-EPROBE_DEFER); - brcmf_acpi_probe(dev, bus_type, settings); - } - return settings; -diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c -index fe4f65756105..6d90be952901 100644 ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c -@@ -6,6 +6,7 @@ - #include <linux/of.h> - #include <linux/of_irq.h> - #include <linux/of_net.h> -+#include <linux/clk.h> - - #include <defs.h> - #include "debug.h" -@@ -65,12 +66,13 @@ static int brcmf_of_get_country_codes(st - return 0; - } - --void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, -- struct brcmf_mp_device *settings) -+int brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, -+ struct brcmf_mp_device *settings) - { - struct brcmfmac_sdio_pd *sdio = &settings->bus.sdio; - struct device_node *root, *np = dev->of_node; - struct of_phandle_args oirq; -+ struct clk *clk; - const char *prop; - int irq; - int err; -@@ -106,15 +108,22 @@ void brcmf_of_probe(struct device *dev, - - if (!board_type) { - of_node_put(root); -- return; -+ return 0; - } - strreplace(board_type, '/', '-'); - settings->board_type = board_type; - } - of_node_put(root); - -+ clk = devm_clk_get_optional_enabled(dev, "lpo"); -+ if (IS_ERR(clk)) -+ return PTR_ERR(clk); -+ -+ brcmf_dbg(INFO, "%s LPO clock\n", clk ? "enable" : "no"); -+ clk_set_rate(clk, 32768); -+ - if (!np || !of_device_is_compatible(np, "brcm,bcm4329-fmac")) -- return; -+ return 0; - - err = brcmf_of_get_country_codes(dev, settings); - if (err) -@@ -123,23 +132,25 @@ void brcmf_of_probe(struct device *dev, - of_get_mac_address(np, settings->mac); - - if (bus_type != BRCMF_BUSTYPE_SDIO) -- return; -+ return 0; - - if (of_property_read_u32(np, "brcm,drive-strength", &val) == 0) - sdio->drive_strength = val; - - /* make sure there are interrupts defined in the node */ - if (of_irq_parse_one(np, 0, &oirq)) -- return; -+ return 0; - - irq = irq_create_of_mapping(&oirq); - if (!irq) { - brcmf_err("interrupt could not be mapped\n"); -- return; -+ return 0; - } - irqf = irqd_get_trigger_type(irq_get_irq_data(irq)); - - sdio->oob_irq_supported = true; - sdio->oob_irq_nr = irq; - sdio->oob_irq_flags = irqf; -+ -+ return 0; - } -diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h -index 10bf52253337..ae124c73fc3b 100644 ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h -@@ -3,11 +3,12 @@ - * Copyright (c) 2014 Broadcom Corporation - */ - #ifdef CONFIG_OF --void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, -- struct brcmf_mp_device *settings); -+int brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, -+ struct brcmf_mp_device *settings); - #else --static void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, -- struct brcmf_mp_device *settings) -+static int brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, -+ struct brcmf_mp_device *settings) - { -+ return 0; - } - #endif /* CONFIG_OF */ -diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c -index 5dee54819fbd..af68cdf0b114 100644 ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c -@@ -2452,6 +2452,9 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) - ret = -ENOMEM; - goto fail; - } -+ ret = PTR_ERR_OR_ZERO(devinfo->settings); -+ if (ret < 0) -+ goto fail; - - bus = kzalloc(sizeof(*bus), GFP_KERNEL); - if (!bus) { -diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c -index 7b936668c1b6..b1727f35217b 100644 ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c -@@ -3943,7 +3943,7 @@ static const struct brcmf_buscore_ops brcmf_sdio_buscore_ops = { - .write32 = brcmf_sdio_buscore_write32, - }; - --static bool -+static int - brcmf_sdio_probe_attach(struct brcmf_sdio *bus) - { - struct brcmf_sdio_dev *sdiodev; -@@ -3953,6 +3953,7 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus) - u32 reg_val; - u32 drivestrength; - u32 enum_base; -+ int ret = -EBADE; - - sdiodev = bus->sdiodev; - sdio_claim_host(sdiodev->func1); -@@ -4001,8 +4002,9 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus) - BRCMF_BUSTYPE_SDIO, - bus->ci->chip, - bus->ci->chiprev); -- if (!sdiodev->settings) { -+ if (IS_ERR_OR_NULL(sdiodev->settings)) { - brcmf_err("Failed to get device parameters\n"); -+ ret = PTR_ERR_OR_ZERO(sdiodev->settings); - goto fail; - } - /* platform specific configuration: -@@ -4071,7 +4073,7 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus) - /* allocate header buffer */ - bus->hdrbuf = kzalloc(MAX_HDR_READ + bus->head_align, GFP_KERNEL); - if (!bus->hdrbuf) -- return false; -+ return -ENOMEM; - /* Locate an appropriately-aligned portion of hdrbuf */ - bus->rxhdr = (u8 *) roundup((unsigned long)&bus->hdrbuf[0], - bus->head_align); -@@ -4082,11 +4084,11 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus) - if (bus->poll) - bus->pollrate = 1; - -- return true; -+ return 0; - - fail: - sdio_release_host(sdiodev->func1); -- return false; -+ return ret; - } - - static int -@@ -4451,8 +4453,10 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) - - /* Allocate private bus interface state */ - bus = kzalloc(sizeof(*bus), GFP_ATOMIC); -- if (!bus) -+ if (!bus) { -+ ret = -ENOMEM; - goto fail; -+ } - - bus->sdiodev = sdiodev; - sdiodev->bus = bus; -@@ -4467,6 +4471,7 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) - dev_name(&sdiodev->func1->dev)); - if (!wq) { - brcmf_err("insufficient memory to create txworkqueue\n"); -+ ret = -ENOMEM; - goto fail; - } - brcmf_sdiod_freezer_count(sdiodev); -@@ -4474,7 +4479,8 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) - bus->brcmf_wq = wq; - - /* attempt to attach to the dongle */ -- if (!(brcmf_sdio_probe_attach(bus))) { -+ ret = brcmf_sdio_probe_attach(bus); -+ if (ret < 0) { - brcmf_err("brcmf_sdio_probe_attach failed\n"); - goto fail; - } -@@ -4546,7 +4552,7 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) - - fail: - brcmf_sdio_remove(bus); -- return NULL; -+ return ERR_PTR(ret); - } - - /* Detach and free everything */ -diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c -index 8afbf529c745..2821c27f317e 100644 ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c -@@ -1272,6 +1272,9 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo, - ret = -ENOMEM; - goto fail; - } -+ ret = PTR_ERR_OR_ZERO(devinfo->settings); -+ if (ret < 0) -+ goto fail; - - if (!brcmf_usb_dlneeded(devinfo)) { - ret = brcmf_alloc(devinfo->dev, devinfo->settings); --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0059-wifi-brcmfmac-add-flag-for-random-seed-during-firmwa.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0059-wifi-brcmfmac-add-flag-for-random-seed-during-firmwa.patch deleted file mode 100644 index 2395329715..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0059-wifi-brcmfmac-add-flag-for-random-seed-during-firmwa.patch +++ /dev/null @@ -1,174 +0,0 @@ -From 29bb45aa5a0be35c43cdfb29e10ca1d951ca1059 Mon Sep 17 00:00:00 2001 -From: Jacobe Zang <jacobe.zang@wesion.com> -Date: Tue, 10 Sep 2024 11:04:14 +0800 -Subject: [PATCH 59/63] wifi: brcmfmac: add flag for random seed during - firmware download - -Providing the random seed to firmware was tied to the fact that the -device has a valid OTP, which worked for some Apple chips. However, -it turns out the BCM43752 device also needs the random seed in order -to get firmware running. Suspect it is simply tied to the firmware -branch used for the device. Introducing a mechanism to allow setting -it for a device through the device table. - -Co-developed-by: Ondrej Jirman <megi@xff.cz> -Signed-off-by: Ondrej Jirman <megi@xff.cz> -Co-developed-by: Arend van Spriel <arend.vanspriel@broadcom.com> -Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> -Signed-off-by: Jacobe Zang <jacobe.zang@wesion.com> -Link: https://lore.kernel.org/r/20240910-wireless-mainline-v14-4-9d80fea5326d@wesion.com -Signed-off-by: Sebastian Reichel <sre@kernel.org> ---- - .../broadcom/brcm80211/brcmfmac/pcie.c | 52 ++++++++++++++++--- - .../broadcom/brcm80211/include/brcm_hw_ids.h | 2 + - 2 files changed, 46 insertions(+), 8 deletions(-) - -diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c -index af68cdf0b114..e4395b1f8c11 100644 ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c -@@ -66,6 +66,7 @@ BRCMF_FW_DEF(4365C, "brcmfmac4365c-pcie"); - BRCMF_FW_DEF(4366B, "brcmfmac4366b-pcie"); - BRCMF_FW_DEF(4366C, "brcmfmac4366c-pcie"); - BRCMF_FW_DEF(4371, "brcmfmac4371-pcie"); -+BRCMF_FW_CLM_DEF(43752, "brcmfmac43752-pcie"); - BRCMF_FW_CLM_DEF(4377B3, "brcmfmac4377b3-pcie"); - BRCMF_FW_CLM_DEF(4378B1, "brcmfmac4378b1-pcie"); - BRCMF_FW_CLM_DEF(4378B3, "brcmfmac4378b3-pcie"); -@@ -104,6 +105,7 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { - BRCMF_FW_ENTRY(BRCM_CC_43664_CHIP_ID, 0xFFFFFFF0, 4366C), - BRCMF_FW_ENTRY(BRCM_CC_43666_CHIP_ID, 0xFFFFFFF0, 4366C), - BRCMF_FW_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371), -+ BRCMF_FW_ENTRY(BRCM_CC_43752_CHIP_ID, 0xFFFFFFFF, 43752), - BRCMF_FW_ENTRY(BRCM_CC_4377_CHIP_ID, 0xFFFFFFFF, 4377B3), /* revision ID 4 */ - BRCMF_FW_ENTRY(BRCM_CC_4378_CHIP_ID, 0x0000000F, 4378B1), /* revision ID 3 */ - BRCMF_FW_ENTRY(BRCM_CC_4378_CHIP_ID, 0xFFFFFFE0, 4378B3), /* revision ID 5 */ -@@ -353,6 +355,7 @@ struct brcmf_pciedev_info { - u16 value); - struct brcmf_mp_device *settings; - struct brcmf_otp_params otp; -+ bool fwseed; - #ifdef DEBUG - u32 console_interval; - bool console_active; -@@ -1715,14 +1718,14 @@ static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo, - memcpy_toio(devinfo->tcm + address, nvram, nvram_len); - brcmf_fw_nvram_free(nvram); - -- if (devinfo->otp.valid) { -+ if (devinfo->fwseed) { - size_t rand_len = BRCMF_RANDOM_SEED_LENGTH; - struct brcmf_random_seed_footer footer = { - .length = cpu_to_le32(rand_len), - .magic = cpu_to_le32(BRCMF_RANDOM_SEED_MAGIC), - }; - -- /* Some Apple chips/firmwares expect a buffer of random -+ /* Some chips/firmwares expect a buffer of random - * data to be present before NVRAM - */ - brcmf_dbg(PCIE, "Download random seed\n"); -@@ -2394,6 +2397,37 @@ static void brcmf_pcie_debugfs_create(struct device *dev) - } - #endif - -+struct brcmf_pcie_drvdata { -+ enum brcmf_fwvendor vendor; -+ bool fw_seed; -+}; -+ -+enum { -+ BRCMF_DRVDATA_CYW, -+ BRCMF_DRVDATA_BCA, -+ BRCMF_DRVDATA_WCC, -+ BRCMF_DRVDATA_WCC_SEED, -+}; -+ -+static const struct brcmf_pcie_drvdata drvdata[] = { -+ [BRCMF_DRVDATA_CYW] = { -+ .vendor = BRCMF_FWVENDOR_CYW, -+ .fw_seed = false, -+ }, -+ [BRCMF_DRVDATA_BCA] = { -+ .vendor = BRCMF_FWVENDOR_BCA, -+ .fw_seed = false, -+ }, -+ [BRCMF_DRVDATA_WCC] = { -+ .vendor = BRCMF_FWVENDOR_WCC, -+ .fw_seed = false, -+ }, -+ [BRCMF_DRVDATA_WCC_SEED] = { -+ .vendor = BRCMF_FWVENDOR_WCC, -+ .fw_seed = true, -+ }, -+}; -+ - /* Forward declaration for pci_match_id() call */ - static const struct pci_device_id brcmf_pcie_devid_table[]; - -@@ -2475,9 +2509,10 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) - bus->bus_priv.pcie = pcie_bus_dev; - bus->ops = &brcmf_pcie_bus_ops; - bus->proto_type = BRCMF_PROTO_MSGBUF; -- bus->fwvid = id->driver_data; - bus->chip = devinfo->coreid; - bus->wowl_supported = pci_pme_capable(pdev, PCI_D3hot); -+ bus->fwvid = drvdata[id->driver_data].vendor; -+ devinfo->fwseed = drvdata[id->driver_data].fw_seed; - dev_set_drvdata(&pdev->dev, bus); - - ret = brcmf_alloc(&devinfo->pdev->dev, devinfo->settings); -@@ -2663,14 +2698,14 @@ static const struct dev_pm_ops brcmf_pciedrvr_pm = { - BRCM_PCIE_VENDOR_ID_BROADCOM, (dev_id), \ - PCI_ANY_ID, PCI_ANY_ID, \ - PCI_CLASS_NETWORK_OTHER << 8, 0xffff00, \ -- BRCMF_FWVENDOR_ ## fw_vend \ -+ BRCMF_DRVDATA_ ## fw_vend \ - } - #define BRCMF_PCIE_DEVICE_SUB(dev_id, subvend, subdev, fw_vend) \ - { \ - BRCM_PCIE_VENDOR_ID_BROADCOM, (dev_id), \ - (subvend), (subdev), \ - PCI_CLASS_NETWORK_OTHER << 8, 0xffff00, \ -- BRCMF_FWVENDOR_ ## fw_vend \ -+ BRCMF_DRVDATA_ ## fw_vend \ - } - - static const struct pci_device_id brcmf_pcie_devid_table[] = { -@@ -2698,9 +2733,10 @@ static const struct pci_device_id brcmf_pcie_devid_table[] = { - BRCMF_PCIE_DEVICE(BRCM_PCIE_4366_5G_DEVICE_ID, BCA), - BRCMF_PCIE_DEVICE(BRCM_PCIE_4371_DEVICE_ID, WCC), - BRCMF_PCIE_DEVICE(BRCM_PCIE_43596_DEVICE_ID, CYW), -- BRCMF_PCIE_DEVICE(BRCM_PCIE_4377_DEVICE_ID, WCC), -- BRCMF_PCIE_DEVICE(BRCM_PCIE_4378_DEVICE_ID, WCC), -- BRCMF_PCIE_DEVICE(BRCM_PCIE_4387_DEVICE_ID, WCC), -+ BRCMF_PCIE_DEVICE(BRCM_PCIE_4377_DEVICE_ID, WCC_SEED), -+ BRCMF_PCIE_DEVICE(BRCM_PCIE_4378_DEVICE_ID, WCC_SEED), -+ BRCMF_PCIE_DEVICE(BRCM_PCIE_4387_DEVICE_ID, WCC_SEED), -+ BRCMF_PCIE_DEVICE(BRCM_PCIE_43752_DEVICE_ID, WCC_SEED), - - { /* end: all zeroes */ } - }; -diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h -index 44684bf1b9ac..c1e22c589d85 100644 ---- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h -+++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h -@@ -52,6 +52,7 @@ - #define BRCM_CC_43664_CHIP_ID 43664 - #define BRCM_CC_43666_CHIP_ID 43666 - #define BRCM_CC_4371_CHIP_ID 0x4371 -+#define BRCM_CC_43752_CHIP_ID 43752 - #define BRCM_CC_4377_CHIP_ID 0x4377 - #define BRCM_CC_4378_CHIP_ID 0x4378 - #define BRCM_CC_4387_CHIP_ID 0x4387 -@@ -94,6 +95,7 @@ - #define BRCM_PCIE_4366_5G_DEVICE_ID 0x43c5 - #define BRCM_PCIE_4371_DEVICE_ID 0x440d - #define BRCM_PCIE_43596_DEVICE_ID 0x4415 -+#define BRCM_PCIE_43752_DEVICE_ID 0x449d - #define BRCM_PCIE_4377_DEVICE_ID 0x4488 - #define BRCM_PCIE_4378_DEVICE_ID 0x4425 - #define BRCM_PCIE_4387_DEVICE_ID 0x4433 --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0060-arm64-dts-rockchip-rk3588-evb1-add-WLAN-controller.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0060-arm64-dts-rockchip-rk3588-evb1-add-WLAN-controller.patch deleted file mode 100644 index a666dc1bc1..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0060-arm64-dts-rockchip-rk3588-evb1-add-WLAN-controller.patch +++ /dev/null @@ -1,138 +0,0 @@ -From 0c8cc557dcc6c70b5ce160d45713f33e52b51f9b Mon Sep 17 00:00:00 2001 -From: Sebastian Reichel <sebastian.reichel@collabora.com> -Date: Fri, 14 Jul 2023 17:38:24 +0200 -Subject: [PATCH 60/63] arm64: dts: rockchip: rk3588-evb1: add WLAN controller - -The RK3588 EVB1 has an onboard AP6275P WLAN/BT module. This adds -support for the WLAN side, which is connected to the second -PCIe bus. The Bluetooth side is connected to UART and handled -separately. - -Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> ---- - .../boot/dts/rockchip/rk3588-evb1-v10.dts | 82 +++++++++++++++++++ - 1 file changed, 82 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts -index 142e685ae513..a2806d69ca52 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts -@@ -258,12 +258,48 @@ vcc5v0_usb: vcc5v0-usb-regulator { - regulator-max-microvolt = <5000000>; - vin-supply = <&vcc5v0_usbdcin>; - }; -+ -+ vccio_wl: vccio-wl { -+ compatible = "regulator-fixed"; -+ regulator-name = "wlan-vddio"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+ regulator-boot-on; -+ vin-supply = <&vcc_1v8_s0>; -+ }; -+ -+ vcc3v3_pciewl_vbat: vcc3v3-pciewl-vbat { -+ compatible = "regulator-fixed"; -+ regulator-name = "wlan-vbat"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ regulator-boot-on; -+ vin-supply = <&vcc_3v3_s0>; -+ }; -+ -+ vcc3v3_wlan: vcc3v3-wlan { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&wifi_pwren>; -+ regulator-name = "wlan-en"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_HIGH>; -+ vin-supply = <&vcc3v3_pciewl_vbat>; -+ }; - }; - - &combphy0_ps { - status = "okay"; - }; - -+&combphy1_ps { -+ status = "okay"; -+}; -+ - &combphy2_psu { - status = "okay"; - }; -@@ -466,6 +502,30 @@ rgmii_phy: ethernet-phy@1 { - }; - }; - -+&pcie2x1l0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie2_0_rst>, <&pcie2_0_wake>, <&pcie2_0_clkreq>, <&wifi_host_wake_irq>; -+ reset-gpios = <&gpio4 RK_PA5 GPIO_ACTIVE_HIGH>; -+ vpcie3v3-supply = <&vcc3v3_wlan>; -+ status = "okay"; -+ -+ pcie@0,0 { -+ reg = <0x200000 0 0 0 0>; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ ranges; -+ device_type = "pci"; -+ bus-range = <0x20 0x2f>; -+ -+ wifi: wifi@0,0 { -+ compatible = "pci14e4,449d"; -+ reg = <0x210000 0 0 0 0>; -+ clocks = <&hym8563>; -+ clock-names = "lpo"; -+ }; -+ }; -+}; -+ - &pcie2x1l1 { - reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; -@@ -536,6 +596,18 @@ hym8563_int: hym8563-int { - }; - - pcie2 { -+ pcie2_0_rst: pcie2-0-rst { -+ rockchip,pins = <4 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ pcie2_0_wake: pcie2-0-wake { -+ rockchip,pins = <4 RK_PA4 4 &pcfg_pull_none>; -+ }; -+ -+ pcie2_0_clkreq: pcie2-0-clkreq { -+ rockchip,pins = <4 RK_PA3 4 &pcfg_pull_none>; -+ }; -+ - pcie2_1_rst: pcie2-1-rst { - rockchip,pins = <4 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; - }; -@@ -574,6 +646,16 @@ usbc0_int: usbc0-int { - rockchip,pins = <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>; - }; - }; -+ -+ wlan { -+ wifi_host_wake_irq: wifi-host-wake-irq { -+ rockchip,pins = <3 RK_PA7 RK_FUNC_GPIO &pcfg_pull_down>; -+ }; -+ -+ wifi_pwren: wifi-pwren { -+ rockchip,pins = <3 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; - }; - - &pwm2 { --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0061-arm64-dts-rockchip-add-and-enable-gpu-node-for-Radxa.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0061-arm64-dts-rockchip-add-and-enable-gpu-node-for-Radxa.patch deleted file mode 100644 index 16a0923d7e..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0061-arm64-dts-rockchip-add-and-enable-gpu-node-for-Radxa.patch +++ /dev/null @@ -1,34 +0,0 @@ -From bc8e649d9cf1d7fef64bac678e7f47ed4f43f3c5 Mon Sep 17 00:00:00 2001 -From: FUKAUMI Naoki <naoki@radxa.com> -Date: Sat, 19 Oct 2024 02:50:08 +0000 -Subject: [PATCH 61/63] arm64: dts: rockchip: add and enable gpu node for Radxa - ROCK 5A - -add gpu node to make it usable on Radxa ROCK 5A. - -Signed-off-by: FUKAUMI Naoki <naoki@radxa.com> -Link: https://lore.kernel.org/r/20241019025008.852-1-naoki@radxa.com -Signed-off-by: Sebastian Reichel <sre@kernel.org> ---- - arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts -index a61864482f1f..2eeec3ffb52b 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts -@@ -166,6 +166,11 @@ &cpu_l3 { - cpu-supply = <&vdd_cpu_lit_s0>; - }; - -+&gpu { -+ mali-supply = <&vdd_gpu_s0>; -+ status = "okay"; -+}; -+ - &i2c0 { - pinctrl-names = "default"; - pinctrl-0 = <&i2c0m2_xfer>; --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0062-arm64-dts-rockchip-Enable-HDMI0-on-rock-5a.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0062-arm64-dts-rockchip-Enable-HDMI0-on-rock-5a.patch deleted file mode 100644 index 0f80010d38..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0062-arm64-dts-rockchip-Enable-HDMI0-on-rock-5a.patch +++ /dev/null @@ -1,98 +0,0 @@ -From dd348abb9979898273e32eac080d237b28744117 Mon Sep 17 00:00:00 2001 -From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> -Date: Sat, 19 Oct 2024 13:12:14 +0300 -Subject: [PATCH 62/63] arm64: dts: rockchip: Enable HDMI0 on rock-5a - -Add the necessary DT changes to enable HDMI0 on Radxa ROCK 5A. - -Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> -Link: https://lore.kernel.org/r/20241019-rk3588-hdmi0-dt-v2-5-466cd80e8ff9@collabora.com -Signed-off-by: Sebastian Reichel <sre@kernel.org> ---- - .../boot/dts/rockchip/rk3588s-rock-5a.dts | 52 +++++++++++++++++++ - 1 file changed, 52 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts -index 2eeec3ffb52b..90db7dba54a3 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts -@@ -5,6 +5,7 @@ - #include <dt-bindings/gpio/gpio.h> - #include <dt-bindings/leds/common.h> - #include <dt-bindings/pinctrl/rockchip.h> -+#include <dt-bindings/soc/rockchip,vop2.h> - #include "rk3588s.dtsi" - - / { -@@ -35,6 +36,17 @@ chosen { - stdout-path = "serial2:1500000n8"; - }; - -+ hdmi0-con { -+ compatible = "hdmi-connector"; -+ type = "d"; -+ -+ port { -+ hdmi0_con_in: endpoint { -+ remote-endpoint = <&hdmi0_out_con>; -+ }; -+ }; -+ }; -+ - leds { - compatible = "gpio-leds"; - pinctrl-names = "default"; -@@ -301,6 +313,31 @@ &gmac1_rgmii_clk - status = "okay"; - }; - -+&hdmi0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&hdmim0_tx0_cec -+ &hdmim1_tx0_hpd -+ &hdmim0_tx0_scl -+ &hdmim0_tx0_sda>; -+ status = "okay"; -+}; -+ -+&hdmi0_in { -+ hdmi0_in_vp0: endpoint { -+ remote-endpoint = <&vp0_out_hdmi0>; -+ }; -+}; -+ -+&hdmi0_out { -+ hdmi0_out_con: endpoint { -+ remote-endpoint = <&hdmi0_con_in>; -+ }; -+}; -+ -+&hdptxphy_hdmi0 { -+ status = "okay"; -+}; -+ - &mdio1 { - rgmii_phy1: ethernet-phy@1 { - /* RTL8211F */ -@@ -793,3 +830,18 @@ &usb_host1_ohci { - &usb_host2_xhci { - status = "okay"; - }; -+ -+&vop_mmu { -+ status = "okay"; -+}; -+ -+&vop { -+ status = "okay"; -+}; -+ -+&vp0 { -+ vp0_out_hdmi0: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { -+ reg = <ROCKCHIP_VOP2_EP_HDMI0>; -+ remote-endpoint = <&hdmi0_in_vp0>; -+ }; -+}; --- -2.39.2 - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0100-rk3588-dtsi-add-hdmi1-controller.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0100-rk3588-dtsi-add-hdmi1-controller.patch deleted file mode 100644 index a11a48df57..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0100-rk3588-dtsi-add-hdmi1-controller.patch +++ /dev/null @@ -1,117 +0,0 @@ -commit bbaaf0bcb523321fdf3caa4fbbc6d7cff732ea3b -Author: Lukas F. Hartmann <lukas@mntre.com> -Date: Tue Mar 5 14:06:47 2024 +0100 - - rk3588: dtsi: add hdmi1 (second HDMI controller) - ---- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi -@@ -25,6 +25,10 @@ - gpio2 = &gpio2; - gpio3 = &gpio3; - gpio4 = &gpio4; -+ hdmi0 = &hdmi0; -+ hdmi1 = &hdmi1; -+ hdptxphy0 = &hdptxphy_hdmi0; -+ hdptxphy1 = &hdptxphy_hdmi1; - i2c0 = &i2c0; - i2c1 = &i2c1; - i2c2 = &i2c2; -@@ -698,6 +702,11 @@ - reg = <0x0 0xfd5e0000 0x0 0x100>; - }; - -+ hdptxphy1_grf: syscon@fd5e4000 { -+ compatible = "rockchip,rk3588-hdptxphy-grf", "syscon"; -+ reg = <0x0 0xfd5e4000 0x0 0x100>; -+ }; -+ - ioc: syscon@fd5f0000 { - compatible = "rockchip,rk3588-ioc", "syscon"; - reg = <0x0 0xfd5f0000 0x0 0x10000>; -@@ -1442,6 +1451,61 @@ - }; - }; - -+ hdmi1: hdmi@fdea0000 { -+ compatible = "rockchip,rk3588-dw-hdmi"; -+ reg = <0x0 0xfdea0000 0x0 0x20000>; -+ interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH 0>, -+ <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH 0>, -+ <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH 0>, -+ <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH 0>, -+ <GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH 0>; -+ clocks = <&cru PCLK_HDMITX1>, -+ <&cru CLK_HDMIHDP1>, -+ <&cru CLK_HDMITX1_EARC>, -+ <&cru CLK_HDMITX1_REF>, -+ <&cru MCLK_I2S6_8CH_TX>, -+ <&cru DCLK_VOP0>, -+ <&cru DCLK_VOP1>, -+ <&cru DCLK_VOP2>, -+ <&cru DCLK_VOP3>, -+ <&cru HCLK_VO1>; -+ clock-names = "pclk", -+ "hpd", -+ "earc", -+ "hdmitx_ref", -+ "aud", -+ "dclk_vp0", -+ "dclk_vp1", -+ "dclk_vp2", -+ "dclk_vp3", -+ "hclk_vo1"; -+ -+ resets = <&cru SRST_HDMITX1_REF>, <&cru SRST_HDMIHDP1>; -+ reset-names = "ref", "hdp"; -+ power-domains = <&power RK3588_PD_VO1>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&hdmim2_tx1_cec &hdmim0_tx1_hpd &hdmim1_tx1_scl &hdmim1_tx1_sda>; -+ reg-io-width = <4>; -+ rockchip,grf = <&sys_grf>; -+ rockchip,vo1_grf = <&vo1_grf>; -+ phys = <&hdptxphy_hdmi1>; -+ phy-names = "hdmi"; -+ status = "disabled"; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ hdmi1_in: port@0 { -+ reg = <0>; -+ }; -+ -+ hdmi1_out: port@1 { -+ reg = <1>; -+ }; -+ }; -+ }; -+ - qos_gpu_m0: qos@fdf35000 { - compatible = "rockchip,rk3588-qos", "syscon"; - reg = <0x0 0xfdf35000 0x0 0x20>; -@@ -2854,6 +2918,23 @@ - status = "disabled"; - }; - -+ hdptxphy_hdmi1: phy@fed70000 { -+ compatible = "rockchip,rk3588-hdptx-phy"; -+ reg = <0x0 0xfed70000 0x0 0x2000>; -+ clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>, <&cru PCLK_HDPTX1>; -+ clock-names = "ref", "apb"; -+ #clock-cells = <0>; -+ #phy-cells = <0>; -+ resets = <&cru SRST_HDPTX1>, <&cru SRST_P_HDPTX1>, -+ <&cru SRST_HDPTX1_INIT>, <&cru SRST_HDPTX1_CMN>, -+ <&cru SRST_HDPTX1_LANE>, <&cru SRST_HDPTX1_ROPLL>, -+ <&cru SRST_HDPTX1_LCPLL>; -+ reset-names = "phy", "apb", "init", "cmn", "lane", "ropll", -+ "lcpll"; -+ rockchip,grf = <&hdptxphy1_grf>; -+ status = "disabled"; -+ }; -+ - usbdp_phy0: phy@fed80000 { - compatible = "rockchip,rk3588-usbdp-phy"; - reg = <0x0 0xfed80000 0x0 0x10000>; diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/0102-drm-panthor-Actually-suspend-IRQs-in-the-unplug-path.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/0102-drm-panthor-Actually-suspend-IRQs-in-the-unplug-path.patch deleted file mode 100644 index cce80931d5..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/0102-drm-panthor-Actually-suspend-IRQs-in-the-unplug-path.patch +++ /dev/null @@ -1,92 +0,0 @@ -From patchwork Mon Mar 25 10:41:11 2024 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [2/2] drm/panthor: Actually suspend IRQs in the unplug path -From: Boris Brezillon <boris.brezillon@collabora.com> -X-Patchwork-Id: 584644 -Message-Id: <20240325104111.3553712-2-boris.brezillon@collabora.com> -To: Boris Brezillon <boris.brezillon@collabora.com>, - Steven Price <steven.price@arm.com>, Liviu Dudau <liviu.dudau@arm.com>, - =?UTF-8?q?Adri=C3=A1n=20Larumbe?= <adrian.larumbe@collabora.com> -Cc: dri-devel@lists.freedesktop.org, - kernel@collabora.com -Date: Mon, 25 Mar 2024 11:41:11 +0100 - -panthor_xxx_irq_suspend() doesn't mask the interrupts if drm_dev_unplug() -has been called, which is always the case when our panthor_xxx_unplug() -helpers are called. Fix that by introducing a panthor_xxx_unplug() helper -that does what panthor_xxx_irq_suspend() except it does it -unconditionally. - -Fixes: 5fe909cae118 ("drm/panthor: Add the device logical block") -Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> ---- -Found inadvertently while debugging another issue. I guess I managed to -call rmmod during a PING and that led to the FW interrupt handler -being executed after the device suspend happened. ---- - drivers/gpu/drm/panthor/panthor_device.h | 8 ++++++++ - drivers/gpu/drm/panthor/panthor_fw.c | 2 +- - drivers/gpu/drm/panthor/panthor_gpu.c | 2 +- - drivers/gpu/drm/panthor/panthor_mmu.c | 2 +- - 4 files changed, 11 insertions(+), 3 deletions(-) - -diff --git a/drivers/gpu/drm/panthor/panthor_device.h b/drivers/gpu/drm/panthor/panthor_device.h -index 51c9d61b6796..ba43d5ea4e96 100644 ---- a/drivers/gpu/drm/panthor/panthor_device.h -+++ b/drivers/gpu/drm/panthor/panthor_device.h -@@ -321,6 +321,14 @@ static irqreturn_t panthor_ ## __name ## _irq_threaded_handler(int irq, void *da - return ret; \ - } \ - \ -+static inline void panthor_ ## __name ## _irq_unplug(struct panthor_irq *pirq) \ -+{ \ -+ pirq->mask = 0; \ -+ gpu_write(pirq->ptdev, __reg_prefix ## _INT_MASK, 0); \ -+ synchronize_irq(pirq->irq); \ -+ atomic_set(&pirq->suspended, true); \ -+} \ -+ \ - static inline void panthor_ ## __name ## _irq_suspend(struct panthor_irq *pirq) \ - { \ - pirq->mask = 0; \ -diff --git a/drivers/gpu/drm/panthor/panthor_fw.c b/drivers/gpu/drm/panthor/panthor_fw.c -index 33c87a59834e..7a9710a38c5f 100644 ---- a/drivers/gpu/drm/panthor/panthor_fw.c -+++ b/drivers/gpu/drm/panthor/panthor_fw.c -@@ -1128,7 +1128,7 @@ void panthor_fw_unplug(struct panthor_device *ptdev) - - /* Make sure the IRQ handler can be called after that point. */ - if (ptdev->fw->irq.irq) -- panthor_job_irq_suspend(&ptdev->fw->irq); -+ panthor_job_irq_unplug(&ptdev->fw->irq); - - panthor_fw_stop(ptdev); - -diff --git a/drivers/gpu/drm/panthor/panthor_gpu.c b/drivers/gpu/drm/panthor/panthor_gpu.c -index 6dbbc4cfbe7e..b84c5b650fd9 100644 ---- a/drivers/gpu/drm/panthor/panthor_gpu.c -+++ b/drivers/gpu/drm/panthor/panthor_gpu.c -@@ -174,7 +174,7 @@ void panthor_gpu_unplug(struct panthor_device *ptdev) - unsigned long flags; - - /* Make sure the IRQ handler is not running after that point. */ -- panthor_gpu_irq_suspend(&ptdev->gpu->irq); -+ panthor_gpu_irq_unplug(&ptdev->gpu->irq); - - /* Wake-up all waiters. */ - spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags); -diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c -index fdd35249169f..1f333cdded0f 100644 ---- a/drivers/gpu/drm/panthor/panthor_mmu.c -+++ b/drivers/gpu/drm/panthor/panthor_mmu.c -@@ -2622,7 +2622,7 @@ int panthor_vm_prepare_mapped_bos_resvs(struct drm_exec *exec, struct panthor_vm - */ - void panthor_mmu_unplug(struct panthor_device *ptdev) - { -- panthor_mmu_irq_suspend(&ptdev->mmu->irq); -+ panthor_mmu_irq_unplug(&ptdev->mmu->irq); - - mutex_lock(&ptdev->mmu->as.slots_lock); - for (u32 i = 0; i < ARRAY_SIZE(ptdev->mmu->as.slots); i++) { diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/3001-display-rockchip-add-schema-for-rk3588-hdmi-tx.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/3001-display-rockchip-add-schema-for-rk3588-hdmi-tx.patch deleted file mode 100644 index 96c4dedb4d..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/3001-display-rockchip-add-schema-for-rk3588-hdmi-tx.patch +++ /dev/null @@ -1,216 +0,0 @@ -From 3e30857760c9f718330676773368c0b03a688357 Mon Sep 17 00:00:00 2001 -From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> -Date: Fri, 26 Jul 2024 03:07:04 +0300 -Subject: [PATCH] dt-bindings: display: rockchip: Add schema for RK3588 HDMI TX - Controller - -Rockchip RK3588 SoC integrates the Synopsys DesignWare HDMI 2.1 -Quad-Pixel (QP) TX controller IP. - -Since this is a new IP block, quite different from those used in the -previous generations of Rockchip SoCs, add a dedicated binding file. - -Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> -Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> ---- - .../rockchip/rockchip,rk3588-dw-hdmi-qp.yaml | 188 ++++++++++++++++++ - 1 file changed, 188 insertions(+) - create mode 100644 Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml - -diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml -new file mode 100644 -index 0000000000000..d8e761865f27e ---- /dev/null -+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml -@@ -0,0 +1,188 @@ -+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: Rockchip DW HDMI QP TX Encoder -+ -+maintainers: -+ - Cristian Ciocaltea <cristian.ciocaltea@collabora.com> -+ -+description: | -+ Rockchip RK3588 SoC integrates the Synopsys DesignWare HDMI QP TX controller -+ IP and a HDMI/eDP TX Combo PHY based on a Samsung IP block, providing the -+ following features, among others: -+ -+ * Fixed Rate Link (FRL) -+ * Display Stream Compression (DSC) -+ * 4K@120Hz and 8K@60Hz video modes -+ * Variable Refresh Rate (VRR) including Quick Media Switching (QMS) -+ * Fast Vactive (FVA) -+ * SCDC I2C DDC access -+ * Multi-stream audio -+ * Enhanced Audio Return Channel (EARC) -+ -+allOf: -+ - $ref: /schemas/sound/dai-common.yaml# -+ -+properties: -+ compatible: -+ enum: -+ - rockchip,rk3588-dw-hdmi-qp -+ -+ reg: -+ maxItems: 1 -+ -+ clocks: -+ items: -+ - description: Peripheral/APB bus clock -+ - description: EARC RX biphase clock -+ - description: Reference clock -+ - description: Audio interface clock -+ - description: TMDS/FRL link clock -+ - description: Video datapath clock -+ -+ clock-names: -+ items: -+ - const: pclk -+ - const: earc -+ - const: ref -+ - const: aud -+ - const: hdp -+ - const: hclk_vo1 -+ -+ interrupts: -+ items: -+ - description: AVP Unit interrupt -+ - description: CEC interrupt -+ - description: eARC RX interrupt -+ - description: Main Unit interrupt -+ - description: HPD interrupt -+ -+ interrupt-names: -+ items: -+ - const: avp -+ - const: cec -+ - const: earc -+ - const: main -+ - const: hpd -+ -+ phys: -+ maxItems: 1 -+ description: The HDMI/eDP PHY -+ -+ ports: -+ $ref: /schemas/graph.yaml#/properties/ports -+ -+ properties: -+ port@0: -+ $ref: /schemas/graph.yaml#/properties/port -+ description: Video port for RGB/YUV input. -+ -+ port@1: -+ $ref: /schemas/graph.yaml#/properties/port -+ description: Video port for HDMI/eDP output. -+ -+ required: -+ - port@0 -+ - port@1 -+ -+ power-domains: -+ maxItems: 1 -+ -+ resets: -+ maxItems: 2 -+ -+ reset-names: -+ items: -+ - const: ref -+ - const: hdp -+ -+ "#sound-dai-cells": -+ const: 0 -+ -+ rockchip,grf: -+ $ref: /schemas/types.yaml#/definitions/phandle -+ description: -+ Some HDMI QP related data is accessed through SYS GRF regs. -+ -+ rockchip,vo-grf: -+ $ref: /schemas/types.yaml#/definitions/phandle -+ description: -+ Additional HDMI QP related data is accessed through VO GRF regs. -+ -+required: -+ - compatible -+ - reg -+ - clocks -+ - clock-names -+ - interrupts -+ - interrupt-names -+ - phys -+ - ports -+ - resets -+ - reset-names -+ - rockchip,grf -+ - rockchip,vo-grf -+ -+unevaluatedProperties: false -+ -+examples: -+ - | -+ #include <dt-bindings/clock/rockchip,rk3588-cru.h> -+ #include <dt-bindings/interrupt-controller/arm-gic.h> -+ #include <dt-bindings/interrupt-controller/irq.h> -+ #include <dt-bindings/power/rk3588-power.h> -+ #include <dt-bindings/reset/rockchip,rk3588-cru.h> -+ -+ soc { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ -+ hdmi@fde80000 { -+ compatible = "rockchip,rk3588-dw-hdmi-qp"; -+ reg = <0x0 0xfde80000 0x0 0x20000>; -+ clocks = <&cru PCLK_HDMITX0>, -+ <&cru CLK_HDMITX0_EARC>, -+ <&cru CLK_HDMITX0_REF>, -+ <&cru MCLK_I2S5_8CH_TX>, -+ <&cru CLK_HDMIHDP0>, -+ <&cru HCLK_VO1>; -+ clock-names = "pclk", "earc", "ref", "aud", "hdp", "hclk_vo1"; -+ interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH 0>, -+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH 0>, -+ <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH 0>, -+ <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH 0>, -+ <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH 0>; -+ interrupt-names = "avp", "cec", "earc", "main", "hpd"; -+ phys = <&hdptxphy_hdmi0>; -+ power-domains = <&power RK3588_PD_VO1>; -+ resets = <&cru SRST_HDMITX0_REF>, <&cru SRST_HDMIHDP0>; -+ reset-names = "ref", "hdp"; -+ rockchip,grf = <&sys_grf>; -+ rockchip,vo-grf = <&vo1_grf>; -+ #sound-dai-cells = <0>; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ port@0 { -+ reg = <0>; -+ -+ hdmi0_in_vp0: endpoint { -+ remote-endpoint = <&vp0_out_hdmi0>; -+ }; -+ }; -+ -+ port@1 { -+ reg = <1>; -+ -+ hdmi0_out_con0: endpoint { -+ remote-endpoint = <&hdmi_con0_in>; -+ }; -+ }; -+ }; -+ }; -+ }; --- -GitLab - diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/4000-mnt-rk3588-dual-hdmi-qp-rockchip.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/4000-mnt-rk3588-dual-hdmi-qp-rockchip.patch deleted file mode 100644 index 0edfd26a7f..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/4000-mnt-rk3588-dual-hdmi-qp-rockchip.patch +++ /dev/null @@ -1,206 +0,0 @@ -diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c -index 353c9e3d5051..9b75bed731ae 100644 ---- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c -+++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c -@@ -26,17 +26,22 @@ - #define RK3588_GRF_SOC_CON2 0x0308 - #define RK3588_HDMI0_HPD_INT_MSK BIT(13) - #define RK3588_HDMI0_HPD_INT_CLR BIT(12) -+#define RK3588_HDMI1_HPD_INT_MSK BIT(15) -+#define RK3588_HDMI1_HPD_INT_CLR BIT(14) - #define RK3588_GRF_SOC_CON7 0x031c - #define RK3588_SET_HPD_PATH_MASK GENMASK(13, 12) - #define RK3588_GRF_SOC_STATUS1 0x0384 - #define RK3588_HDMI0_LEVEL_INT BIT(16) -+#define RK3588_HDMI1_LEVEL_INT BIT(24) - #define RK3588_GRF_VO1_CON3 0x000c -+#define RK3588_GRF_VO1_CON6 0x0018 - #define RK3588_SCLIN_MASK BIT(9) - #define RK3588_SDAIN_MASK BIT(10) - #define RK3588_MODE_MASK BIT(11) - #define RK3588_I2S_SEL_MASK BIT(13) - #define RK3588_GRF_VO1_CON9 0x0024 - #define RK3588_HDMI0_GRANT_SEL BIT(10) -+#define RK3588_HDMI1_GRANT_SEL BIT(12) - - #define HIWORD_UPDATE(val, mask) (val | (mask) << 16) - -@@ -50,6 +55,8 @@ struct rockchip_hdmi_qp { - struct phy *phy; - struct gpio_desc *enable_gpio; - struct delayed_work hpd_work; -+ -+ u8 id; - }; - - static struct rockchip_hdmi_qp *to_rockchip_hdmi_qp(struct drm_encoder *encoder) -@@ -194,19 +201,30 @@ dw_hdmi_qp_rk3588_read_hpd(struct dw_hdmi_qp *dw_hdmi, void *data) - - regmap_read(hdmi->regmap, RK3588_GRF_SOC_STATUS1, &val); - -- return val & RK3588_HDMI0_LEVEL_INT ? -- connector_status_connected : connector_status_disconnected; -+ if (hdmi->id == 0) -+ return val & RK3588_HDMI0_LEVEL_INT ? -+ connector_status_connected : connector_status_disconnected; -+ else -+ return val & RK3588_HDMI1_LEVEL_INT ? -+ connector_status_connected : connector_status_disconnected; - } - - static void dw_hdmi_qp_rk3588_setup_hpd(struct dw_hdmi_qp *dw_hdmi, void *data) - { - struct rockchip_hdmi_qp *hdmi = (struct rockchip_hdmi_qp *)data; - -- regmap_write(hdmi->regmap, -- RK3588_GRF_SOC_CON2, -- HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_CLR, -- RK3588_HDMI0_HPD_INT_CLR | -- RK3588_HDMI0_HPD_INT_MSK)); -+ if (hdmi->id == 0) -+ regmap_write(hdmi->regmap, -+ RK3588_GRF_SOC_CON2, -+ HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_CLR, -+ RK3588_HDMI0_HPD_INT_CLR | -+ RK3588_HDMI0_HPD_INT_MSK)); -+ else -+ regmap_write(hdmi->regmap, -+ RK3588_GRF_SOC_CON2, -+ HIWORD_UPDATE(RK3588_HDMI1_HPD_INT_CLR, -+ RK3588_HDMI1_HPD_INT_CLR | -+ RK3588_HDMI1_HPD_INT_MSK)); - } - - static const struct dw_hdmi_qp_phy_ops rk3588_hdmi_phy_ops = { -@@ -239,8 +257,12 @@ static irqreturn_t dw_hdmi_qp_rk3588_hardirq(int irq, void *dev_id) - regmap_read(hdmi->regmap, RK3588_GRF_SOC_STATUS1, &intr_stat); - - if (intr_stat) { -- val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_MSK, -- RK3588_HDMI0_HPD_INT_MSK); -+ if (hdmi->id == 0) -+ val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_MSK, -+ RK3588_HDMI0_HPD_INT_MSK); -+ else -+ val = HIWORD_UPDATE(RK3588_HDMI1_HPD_INT_MSK, -+ RK3588_HDMI1_HPD_INT_MSK); - regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val); - return IRQ_WAKE_THREAD; - } -@@ -258,16 +280,29 @@ static irqreturn_t dw_hdmi_qp_rk3588_irq(int irq, void *dev_id) - if (!intr_stat) - return IRQ_NONE; - -- val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_CLR, -- RK3588_HDMI0_HPD_INT_CLR); -- regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val); -+ if (hdmi->id == 0) { -+ val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_CLR, -+ RK3588_HDMI0_HPD_INT_CLR); -+ regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val); - -- debounce_ms = intr_stat & RK3588_HDMI0_LEVEL_INT ? 150 : 20; -- mod_delayed_work(system_wq, &hdmi->hpd_work, -- msecs_to_jiffies(debounce_ms)); -+ debounce_ms = intr_stat & RK3588_HDMI0_LEVEL_INT ? 150 : 20; -+ mod_delayed_work(system_wq, &hdmi->hpd_work, -+ msecs_to_jiffies(debounce_ms)); - -- val |= HIWORD_UPDATE(0, RK3588_HDMI0_HPD_INT_MSK); -- regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val); -+ val |= HIWORD_UPDATE(0, RK3588_HDMI0_HPD_INT_MSK); -+ regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val); -+ } else { -+ val = HIWORD_UPDATE(RK3588_HDMI1_HPD_INT_CLR, -+ RK3588_HDMI1_HPD_INT_CLR); -+ regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val); -+ -+ debounce_ms = intr_stat & RK3588_HDMI1_LEVEL_INT ? 150 : 20; -+ mod_delayed_work(system_wq, &hdmi->hpd_work, -+ msecs_to_jiffies(debounce_ms)); -+ -+ val |= HIWORD_UPDATE(0, RK3588_HDMI1_HPD_INT_MSK); -+ regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val); -+ } - - return IRQ_HANDLED; - } -@@ -290,6 +325,7 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master, - struct rockchip_hdmi_qp *hdmi; - int ret, irq; - u32 val; -+ u8 id; - - if (!pdev->dev.of_node) - return -ENODEV; -@@ -302,7 +338,12 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master, - if (!plat_data.phy_ops) - return -ENODEV; - -+ id = of_alias_get_id(pdev->dev.of_node, "hdmi"); -+ if (id < 0) -+ id = 0; -+ - plat_data.phy_data = hdmi; -+ hdmi->id = id; - hdmi->dev = &pdev->dev; - - encoder = &hdmi->encoder.encoder; -@@ -335,17 +376,27 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master, - HIWORD_UPDATE(RK3588_SDAIN_MASK, RK3588_SDAIN_MASK) | - HIWORD_UPDATE(RK3588_MODE_MASK, RK3588_MODE_MASK) | - HIWORD_UPDATE(RK3588_I2S_SEL_MASK, RK3588_I2S_SEL_MASK); -- regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON3, val); -+ if (hdmi->id == 0) -+ regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON3, val); -+ else -+ regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON6, val); - - val = HIWORD_UPDATE(RK3588_SET_HPD_PATH_MASK, - RK3588_SET_HPD_PATH_MASK); - regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON7, val); - -- val = HIWORD_UPDATE(RK3588_HDMI0_GRANT_SEL, -- RK3588_HDMI0_GRANT_SEL); -+ if (hdmi->id == 0) -+ val = HIWORD_UPDATE(RK3588_HDMI0_GRANT_SEL, -+ RK3588_HDMI0_GRANT_SEL); -+ else -+ val = HIWORD_UPDATE(RK3588_HDMI1_GRANT_SEL, -+ RK3588_HDMI1_GRANT_SEL); - regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON9, val); - -- val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_MSK, RK3588_HDMI0_HPD_INT_MSK); -+ if (hdmi->id == 0) -+ val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_MSK, RK3588_HDMI0_HPD_INT_MSK); -+ else -+ val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_MSK, RK3588_HDMI1_HPD_INT_MSK); - regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val); - - INIT_DELAYED_WORK(&hdmi->hpd_work, dw_hdmi_qp_rk3588_hpd_work); -@@ -419,14 +470,22 @@ static int __maybe_unused dw_hdmi_qp_rockchip_resume(struct device *dev) - HIWORD_UPDATE(RK3588_SDAIN_MASK, RK3588_SDAIN_MASK) | - HIWORD_UPDATE(RK3588_MODE_MASK, RK3588_MODE_MASK) | - HIWORD_UPDATE(RK3588_I2S_SEL_MASK, RK3588_I2S_SEL_MASK); -- regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON3, val); -+ if (hdmi->id == 0) -+ regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON3, val); -+ else -+ regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON6, val); - - val = HIWORD_UPDATE(RK3588_SET_HPD_PATH_MASK, - RK3588_SET_HPD_PATH_MASK); - regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON7, val); - -- val = HIWORD_UPDATE(RK3588_HDMI0_GRANT_SEL, -- RK3588_HDMI0_GRANT_SEL); -+ if (hdmi->id == 0) -+ val = HIWORD_UPDATE(RK3588_HDMI0_GRANT_SEL, -+ RK3588_HDMI0_GRANT_SEL); -+ else -+ val = HIWORD_UPDATE(RK3588_HDMI1_GRANT_SEL, -+ RK3588_HDMI1_GRANT_SEL); -+ - regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON9, val); - - dw_hdmi_qp_resume(dev, hdmi->hdmi); diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/4001-mnt-rk3588-dual-hdmi-vop2-pll.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/4001-mnt-rk3588-dual-hdmi-vop2-pll.patch deleted file mode 100644 index f9f74ec9be..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/4001-mnt-rk3588-dual-hdmi-vop2-pll.patch +++ /dev/null @@ -1,83 +0,0 @@ -diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c -index c68d76b25080..9c791268401b 100644 ---- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c -+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c -@@ -218,6 +218,7 @@ struct vop2 { - struct clk *pclk; - // [CC:] hack to support additional display modes - struct clk *hdmi0_phy_pll; -+ struct clk *hdmi1_phy_pll; - /* list_head of internal clk */ - struct list_head clk_list_head; - -@@ -1753,15 +1754,24 @@ static unsigned long rk3588_calc_cru_cfg(struct vop2_video_port *vp, int id, - int K = 1; - - if (vop2_output_if_is_hdmi(id)) { -- if (vop2->data->soc_id == 3588 && id == ROCKCHIP_VOP2_EP_HDMI0 && -- vop2->hdmi0_phy_pll) { -- const char *clk_src_name = "hdmi_edp0_clk_src"; -- const char *clk_parent_name = "dclk"; -- const char *pixclk_name = "hdmi_edp0_pixclk"; -- const char *dclk_name = "hdmi_edp0_dclk"; -+ if (vop2->data->soc_id == 3588 && -+ ((id == ROCKCHIP_VOP2_EP_HDMI0 && vop2->hdmi0_phy_pll) || -+ (id == ROCKCHIP_VOP2_EP_HDMI1 && vop2->hdmi1_phy_pll))) { - struct vop2_clk *if_clk_src, *if_clk_parent, *if_pixclk, *if_dclk, *dclk, *dclk_core, *dclk_out; -+ const char *clk_src_name, *clk_parent_name, *pixclk_name, *dclk_name; - char clk_name[32]; - int ret; -+ clk_parent_name = "dclk"; -+ -+ if (id == ROCKCHIP_VOP2_EP_HDMI0) { -+ clk_src_name = "hdmi_edp0_clk_src"; -+ pixclk_name = "hdmi_edp0_pixclk"; -+ dclk_name = "hdmi_edp0_dclk"; -+ } else { -+ clk_src_name = "hdmi_edp1_clk_src"; -+ pixclk_name = "hdmi_edp1_pixclk"; -+ dclk_name = "hdmi_edp1_dclk"; -+ } - - if_clk_src = vop2_clk_get(vop2, clk_src_name); - snprintf(clk_name, sizeof(clk_name), "%s%d", clk_parent_name, vp->id); -@@ -2242,6 +2252,17 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, - __clk_get_name(vp->dclk)); - } - -+ clock = dclk->rate; -+ } else if (rkencoder->crtc_endpoint_id == ROCKCHIP_VOP2_EP_HDMI1) { -+ clk_get_rate(vop2->hdmi1_phy_pll); -+ -+ if (mode->crtc_clock <= VOP2_MAX_DCLK_RATE) { -+ ret = clk_set_parent(vp->dclk, vop2->hdmi1_phy_pll); -+ if (ret < 0) -+ DRM_WARN("failed to set clock parent for %s\n", -+ __clk_get_name(vp->dclk)); -+ } -+ - clock = dclk->rate; - } - } -@@ -3630,7 +3651,7 @@ static int vop2_clk_init(struct vop2 *vop2) - - INIT_LIST_HEAD(&vop2->clk_list_head); - -- if (vop2->data->soc_id < 3588 || vop2->hdmi0_phy_pll == NULL) -+ if (vop2->data->soc_id < 3588 || vop2->hdmi0_phy_pll == NULL || vop2->hdmi1_phy_pll == NULL) - return 0; - - list_for_each_entry_safe(clk, n, &vop2->clk_list_head, list) { -@@ -3745,6 +3766,12 @@ static int vop2_bind(struct device *dev, struct device *master, void *data) - return PTR_ERR(vop2->hdmi0_phy_pll); - } - -+ vop2->hdmi1_phy_pll = devm_clk_get_optional(vop2->drm->dev, "hdmi1_phy_pll"); -+ if (IS_ERR(vop2->hdmi1_phy_pll)) { -+ DRM_DEV_ERROR(vop2->dev, "failed to get hdmi1_phy_pll source\n"); -+ return PTR_ERR(vop2->hdmi1_phy_pll); -+ } -+ - vop2->irq = platform_get_irq(pdev, 0); - if (vop2->irq < 0) { - drm_err(vop2->drm, "cannot find irq for vop2\n"); diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/5001-rk3588-dsi2-driver.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/5001-rk3588-dsi2-driver.patch deleted file mode 100644 index 6a99437b2a..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/5001-rk3588-dsi2-driver.patch +++ /dev/null @@ -1,3303 +0,0 @@ -commit 6d1a6296f7fdbb4ebe27b45d041ff60aa906cc7b -Author: Lukas F. Hartmann <lukas@mntre.com> -Date: Wed Oct 2 18:20:44 2024 +0200 - - rk3588: add rockchip dsi2 WIP driver and dsi phy driver - - Co-authored-by: Heiko Stuebner <heiko.stuebner@cherry.de> - -diff --git a/Documentation/devicetree/bindings/phy/rockchip,rk3588-mipi-dcphy.yaml b/Documentation/devicetree/bindings/phy/rockchip,rk3588-mipi-dcphy.yaml -new file mode 100644 -index 0000000..01c1365 ---- /dev/null -+++ b/Documentation/devicetree/bindings/phy/rockchip,rk3588-mipi-dcphy.yaml -@@ -0,0 +1,76 @@ -+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/phy/phy-rockchip-mipidc.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: Rockchip MIPI CSI/DSI PHY with Samsung IP block -+ -+maintainers: -+ - Guochun Huang <hero.huang@rock-chips.com> -+ - Heiko Stuebner <heiko@sntech.de> -+ -+properties: -+ compatible: -+ enum: -+ - rockchip,rk3588-mipi-dcphy -+ -+ reg: -+ maxItems: 1 -+ -+ "#phy-cells": -+ const: 0 -+ -+ clocks: -+ maxItems: 2 -+ -+ clock-names: -+ items: -+ - const: pclk -+ - const: ref -+ -+ resets: -+ maxItems: 4 -+ -+ reset-names: -+ items: -+ - const: m_phy -+ - const: apb -+ - const: grf -+ - const: s_phy -+ -+ rockchip,grf: -+ $ref: /schemas/types.yaml#/definitions/phandle -+ description: -+ Phandle to the syscon managing the 'mipi dcphy general register files'. -+ -+required: -+ - compatible -+ - reg -+ - clocks -+ - clock-names -+ - resets -+ - reset-names -+ - "#phy-cells" -+ -+additionalProperties: false -+ -+examples: -+ - | -+ #include <dt-bindings/clock/rockchip,rk3588-cru.h> -+ #include <dt-bindings/reset/rockchip,rk3588-cru.h> -+ -+ mipidcphy0: phy@feda0000 { -+ compatible = "rockchip,rk3588-mipi-dcphy"; -+ reg = <0x0 0xfeda0000 0x0 0x10000>; -+ clocks = <&cru PCLK_MIPI_DCPHY0>, -+ <&cru CLK_USBDPPHY_MIPIDCPPHY_REF>; -+ clock-names = "pclk", "ref"; -+ resets = <&cru SRST_M_MIPI_DCPHY0>, -+ <&cru SRST_P_MIPI_DCPHY0>, -+ <&cru SRST_P_MIPI_DCPHY0_GRF>, -+ <&cru SRST_S_MIPI_DCPHY0>; -+ reset-names = "m_phy", "apb", "grf", "s_phy"; -+ rockchip,grf = <&mipidcphy0_grf>; -+ #phy-cells = <0>; -+ }; -diff --git a/drivers/gpu/drm/rockchip/Makefile b/drivers/gpu/drm/rockchip/Makefile -index 3eab662..bdfb7a6 100644 ---- a/drivers/gpu/drm/rockchip/Makefile -+++ b/drivers/gpu/drm/rockchip/Makefile -@@ -12,7 +12,7 @@ rockchipdrm-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o - rockchipdrm-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o - rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o - rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI_QP) += dw_hdmi_qp-rockchip.o --rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi-rockchip.o -+rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi-rockchip.o dw-mipi-dsi2-rockchip.o - rockchipdrm-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o - rockchipdrm-$(CONFIG_ROCKCHIP_LVDS) += rockchip_lvds.o - rockchipdrm-$(CONFIG_ROCKCHIP_RGB) += rockchip_rgb.o -diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c -new file mode 100644 -index 0000000..e978f95 ---- /dev/null -+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c -@@ -0,0 +1,1519 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Copyright (C) Rockchip Electronics Co.Ltd -+ * Author: -+ * Guochun Huang <hero.huang@rock-chips.com> -+ */ -+ -+#include <linux/clk.h> -+#include <linux/component.h> -+#include <linux/gpio.h> -+#include <linux/iopoll.h> -+#include <linux/math64.h> -+#include <linux/media-bus-format.h> -+#include <linux/module.h> -+#include <linux/of_device.h> -+#include <linux/of_gpio.h> -+#include <linux/of_platform.h> -+#include <linux/pm_runtime.h> -+#include <linux/platform_device.h> -+#include <linux/regmap.h> -+#include <linux/reset.h> -+#include <linux/mfd/syscon.h> -+#include <linux/phy/phy.h> -+ -+#include <drm/display/drm_dsc.h> -+#include <drm/drm_atomic_helper.h> -+#include <drm/drm_crtc.h> -+#include <drm/drm_crtc_helper.h> -+#include <drm/drm_mipi_dsi.h> -+#include <drm/drm_of.h> -+#include <drm/drm_panel.h> -+#include <video/mipi_display.h> -+#include <video/videomode.h> -+#include <linux/unaligned.h> -+#include <drm/drm_panel.h> -+#include <drm/drm_connector.h> -+#include <drm/drm_probe_helper.h> -+#include <drm/drm_simple_kms_helper.h> -+ -+#include <uapi/linux/videodev2.h> -+ -+#include "rockchip_drm_drv.h" -+#include "rockchip_drm_vop.h" -+ -+#define UPDATE(v, h, l) (((v) << (l)) & GENMASK((h), (l))) -+ -+#define DSI2_PWR_UP 0x000c -+#define RESET 0 -+#define POWER_UP BIT(0) -+#define CMD_TX_MODE(x) UPDATE(x, 24, 24) -+#define DSI2_SOFT_RESET 0x0010 -+#define SYS_RSTN BIT(2) -+#define PHY_RSTN BIT(1) -+#define IPI_RSTN BIT(0) -+#define INT_ST_MAIN 0x0014 -+#define DSI2_MODE_CTRL 0x0018 -+#define DSI2_MODE_STATUS 0x001c -+#define DSI2_CORE_STATUS 0x0020 -+#define PRI_RD_DATA_AVAIL BIT(26) -+#define PRI_FIFOS_NOT_EMPTY BIT(25) -+#define PRI_BUSY BIT(24) -+#define CRI_RD_DATA_AVAIL BIT(18) -+#define CRT_FIFOS_NOT_EMPTY BIT(17) -+#define CRI_BUSY BIT(16) -+#define IPI_FIFOS_NOT_EMPTY BIT(9) -+#define IPI_BUSY BIT(8) -+#define CORE_FIFOS_NOT_EMPTY BIT(1) -+#define CORE_BUSY BIT(0) -+#define MANUAL_MODE_CFG 0x0024 -+#define MANUAL_MODE_EN BIT(0) -+#define DSI2_TIMEOUT_HSTX_CFG 0x0048 -+#define TO_HSTX(x) UPDATE(x, 15, 0) -+#define DSI2_TIMEOUT_HSTXRDY_CFG 0x004c -+#define TO_HSTXRDY(x) UPDATE(x, 15, 0) -+#define DSI2_TIMEOUT_LPRX_CFG 0x0050 -+#define TO_LPRXRDY(x) UPDATE(x, 15, 0) -+#define DSI2_TIMEOUT_LPTXRDY_CFG 0x0054 -+#define TO_LPTXRDY(x) UPDATE(x, 15, 0) -+#define DSI2_TIMEOUT_LPTXTRIG_CFG 0x0058 -+#define TO_LPTXTRIG(x) UPDATE(x, 15, 0) -+#define DSI2_TIMEOUT_LPTXULPS_CFG 0x005c -+#define TO_LPTXULPS(x) UPDATE(x, 15, 0) -+#define DSI2_TIMEOUT_BTA_CFG 0x60 -+#define TO_BTA(x) UPDATE(x, 15, 0) -+ -+#define DSI2_PHY_MODE_CFG 0x0100 -+#define PPI_WIDTH(x) UPDATE(x, 9, 8) -+#define PHY_LANES(x) UPDATE(x - 1, 5, 4) -+#define PHY_TYPE(x) UPDATE(x, 0, 0) -+#define DSI2_PHY_CLK_CFG 0X0104 -+#define PHY_LPTX_CLK_DIV(x) UPDATE(x, 12, 8) -+#define CLK_TYPE_MASK BIT(0) -+#define NON_CONTINUOUS_CLK BIT(0) -+#define CONTIUOUS_CLK 0 -+#define DSI2_PHY_LP2HS_MAN_CFG 0x010c -+#define PHY_LP2HS_TIME(x) UPDATE(x, 28, 0) -+#define DSI2_PHY_HS2LP_MAN_CFG 0x0114 -+#define PHY_HS2LP_TIME(x) UPDATE(x, 28, 0) -+#define DSI2_PHY_MAX_RD_T_MAN_CFG 0x011c -+#define PHY_MAX_RD_TIME(x) UPDATE(x, 26, 0) -+#define DSI2_PHY_ESC_CMD_T_MAN_CFG 0x0124 -+#define PHY_ESC_CMD_TIME(x) UPDATE(x, 28, 0) -+#define DSI2_PHY_ESC_BYTE_T_MAN_CFG 0x012c -+#define PHY_ESC_BYTE_TIME(x) UPDATE(x, 28, 0) -+ -+#define DSI2_PHY_IPI_RATIO_MAN_CFG 0x0134 -+#define PHY_IPI_RATIO(x) UPDATE(x, 21, 0) -+#define DSI2_PHY_SYS_RATIO_MAN_CFG 0x013C -+#define PHY_SYS_RATIO(x) UPDATE(x, 16, 0) -+ -+#define DSI2_DSI_GENERAL_CFG 0x0200 -+#define BTA_EN BIT(1) -+#define EOTP_TX_EN BIT(0) -+#define DSI2_DSI_VCID_CFG 0x0204 -+#define TX_VCID(x) UPDATE(x, 1, 0) -+#define DSI2_DSI_SCRAMBLING_CFG 0x0208 -+#define SCRAMBLING_SEED(x) UPDATE(x, 31, 16) -+#define SCRAMBLING_EN BIT(0) -+#define DSI2_DSI_VID_TX_CFG 0x020c -+#define LPDT_DISPLAY_CMD_EN BIT(20) -+#define BLK_VFP_HS_EN BIT(14) -+#define BLK_VBP_HS_EN BIT(13) -+#define BLK_VSA_HS_EN BIT(12) -+#define BLK_HFP_HS_EN BIT(6) -+#define BLK_HBP_HS_EN BIT(5) -+#define BLK_HSA_HS_EN BIT(4) -+#define VID_MODE_TYPE(x) UPDATE(x, 1, 0) -+#define DSI2_CRI_TX_HDR 0x02c0 -+#define CMD_TX_MODE(x) UPDATE(x, 24, 24) -+#define DSI2_CRI_TX_PLD 0x02c4 -+#define DSI2_CRI_RX_HDR 0x02c8 -+#define DSI2_CRI_RX_PLD 0x02cc -+ -+#define DSI2_IPI_COLOR_MAN_CFG 0x0300 -+#define IPI_DEPTH(x) UPDATE(x, 7, 4) -+#define IPI_DEPTH_5_6_5_BITS 0x02 -+#define IPI_DEPTH_6_BITS 0x03 -+#define IPI_DEPTH_8_BITS 0x05 -+#define IPI_DEPTH_10_BITS 0x06 -+#define IPI_FORMAT(x) UPDATE(x, 3, 0) -+#define IPI_FORMAT_RGB 0x0 -+#define IPI_FORMAT_DSC 0x0b -+#define DSI2_IPI_VID_HSA_MAN_CFG 0x0304 -+#define VID_HSA_TIME(x) UPDATE(x, 29, 0) -+#define DSI2_IPI_VID_HBP_MAN_CFG 0x030c -+#define VID_HBP_TIME(x) UPDATE(x, 29, 0) -+#define DSI2_IPI_VID_HACT_MAN_CFG 0x0314 -+#define VID_HACT_TIME(x) UPDATE(x, 29, 0) -+#define DSI2_IPI_VID_HLINE_MAN_CFG 0x031c -+#define VID_HLINE_TIME(x) UPDATE(x, 29, 0) -+#define DSI2_IPI_VID_VSA_MAN_CFG 0x0324 -+#define VID_VSA_LINES(x) UPDATE(x, 9, 0) -+#define DSI2_IPI_VID_VBP_MAN_CFG 0X032C -+#define VID_VBP_LINES(x) UPDATE(x, 9, 0) -+#define DSI2_IPI_VID_VACT_MAN_CFG 0X0334 -+#define VID_VACT_LINES(x) UPDATE(x, 13, 0) -+#define DSI2_IPI_VID_VFP_MAN_CFG 0X033C -+#define VID_VFP_LINES(x) UPDATE(x, 9, 0) -+#define DSI2_IPI_PIX_PKT_CFG 0x0344 -+#define MAX_PIX_PKT(x) UPDATE(x, 15, 0) -+ -+#define DSI2_INT_ST_PHY 0x0400 -+#define DSI2_INT_MASK_PHY 0x0404 -+#define DSI2_INT_ST_TO 0x0410 -+#define DSI2_INT_MASK_TO 0x0414 -+#define DSI2_INT_ST_ACK 0x0420 -+#define DSI2_INT_MASK_ACK 0x0424 -+#define DSI2_INT_ST_IPI 0x0430 -+#define DSI2_INT_MASK_IPI 0x0434 -+#define DSI2_INT_ST_FIFO 0x0440 -+#define DSI2_INT_MASK_FIFO 0x0444 -+#define DSI2_INT_ST_PRI 0x0450 -+#define DSI2_INT_MASK_PRI 0x0454 -+#define DSI2_INT_ST_CRI 0x0460 -+#define DSI2_INT_MASK_CRI 0x0464 -+#define DSI2_INT_FORCE_CRI 0x0468 -+#define DSI2_MAX_REGISGER DSI2_INT_FORCE_CRI -+ -+#define MODE_STATUS_TIMEOUT_US 10000 -+#define CMD_PKT_STATUS_TIMEOUT_US 20000 -+#define PSEC_PER_SEC 1000000000000LL -+ -+#define GRF_REG_FIELD(reg, lsb, msb) (((reg) << 16) | ((lsb) << 8) | (msb)) -+ -+enum vid_mode_type { -+ VID_MODE_TYPE_NON_BURST_SYNC_PULSES, -+ VID_MODE_TYPE_NON_BURST_SYNC_EVENTS, -+ VID_MODE_TYPE_BURST, -+}; -+ -+enum mode_ctrl { -+ IDLE_MODE, -+ AUTOCALC_MODE, -+ COMMAND_MODE, -+ VIDEO_MODE, -+ DATA_STREAM_MODE, -+ VIDE_TEST_MODE, -+ DATA_STREAM_TEST_MODE, -+}; -+ -+enum grf_reg_fields { -+ TXREQCLKHS_EN, -+ GATING_EN, -+ IPI_SHUTDN, -+ IPI_COLORM, -+ IPI_COLOR_DEPTH, -+ IPI_FORMAT, -+ MAX_FIELDS, -+}; -+ -+enum phy_type { -+ DPHY, -+ CPHY, -+}; -+ -+enum ppi_width { -+ PPI_WIDTH_8_BITS, -+ PPI_WIDTH_16_BITS, -+ PPI_WIDTH_32_BITS, -+}; -+ -+struct cmd_header { -+ u8 cmd_type; -+ u8 delay; -+ u8 payload_length; -+}; -+ -+struct dw_mipi_dsi2_plat_data { -+ const u32 *dsi0_grf_reg_fields; -+ const u32 *dsi1_grf_reg_fields; -+ unsigned long long dphy_max_bit_rate_per_lane; -+ unsigned long long cphy_max_symbol_rate_per_lane; -+ -+}; -+ -+struct dw_mipi_dsi2 { -+ struct drm_device *drm_dev; -+ struct rockchip_encoder encoder; -+ struct drm_connector connector; -+ struct drm_bridge *bridge; -+ struct mipi_dsi_host host; -+ struct drm_panel *panel; -+ struct drm_display_mode mode; -+ struct device *dev; -+ struct device_node *client; -+ struct regmap *grf; -+ struct clk *pclk; -+ struct clk *sys_clk; -+ bool phy_enabled; -+ struct phy *dcphy; -+ union phy_configure_opts phy_opts; -+ -+ bool disable_hold_mode; -+ bool c_option; -+ bool scrambling_en; -+ bool dsc_enable; -+ -+ struct drm_dsc_picture_parameter_set *pps; -+ struct regmap *regmap; -+ struct reset_control *apb_rst; -+ int irq; -+ int id; -+ -+ unsigned int lane_hs_rate; /* Mbps or Msps per lane */ -+ u32 channel; -+ u32 lanes; -+ u32 format; -+ unsigned long mode_flags; -+ -+ const struct dw_mipi_dsi2_plat_data *pdata; -+ -+ struct gpio_desc *te_gpio; -+}; -+ -+static inline struct dw_mipi_dsi2 *host_to_dsi2(struct mipi_dsi_host *host) -+{ -+ return container_of(host, struct dw_mipi_dsi2, host); -+} -+ -+static inline struct dw_mipi_dsi2 *con_to_dsi2(struct drm_connector *con) -+{ -+ return container_of(con, struct dw_mipi_dsi2, connector); -+} -+ -+static inline struct dw_mipi_dsi2 *encoder_to_dsi2(struct drm_encoder *encoder) -+{ -+ struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder); -+ -+ return container_of(rkencoder, struct dw_mipi_dsi2, encoder); -+} -+ -+static void grf_field_write(struct dw_mipi_dsi2 *dsi2, enum grf_reg_fields index, -+ unsigned int val) -+{ -+ const u32 field = dsi2->id ? -+ dsi2->pdata->dsi1_grf_reg_fields[index] : -+ dsi2->pdata->dsi0_grf_reg_fields[index]; -+ u16 reg; -+ u8 msb, lsb; -+ -+ if (!field) -+ return; -+ -+ reg = (field >> 16) & 0xffff; -+ lsb = (field >> 8) & 0xff; -+ msb = (field >> 0) & 0xff; -+ -+ regmap_write(dsi2->grf, reg, (val << lsb) | (GENMASK(msb, lsb) << 16)); -+} -+ -+static int cri_fifos_wait_avail(struct dw_mipi_dsi2 *dsi2) -+{ -+ u32 sts, mask; -+ int ret; -+ -+ mask = CRI_BUSY | CRT_FIFOS_NOT_EMPTY; -+ ret = regmap_read_poll_timeout(dsi2->regmap, DSI2_CORE_STATUS, sts, -+ !(sts & mask), 0, -+ CMD_PKT_STATUS_TIMEOUT_US); -+ if (ret < 0) { -+ DRM_DEV_ERROR(dsi2->dev, "command interface is busy\n"); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static void dw_mipi_dsi2_irq_enable(struct dw_mipi_dsi2 *dsi2, bool enable) -+{ -+ if (enable) { -+ regmap_write(dsi2->regmap, DSI2_INT_MASK_PHY, 0x1); -+ regmap_write(dsi2->regmap, DSI2_INT_MASK_TO, 0xf); -+ regmap_write(dsi2->regmap, DSI2_INT_MASK_ACK, 0x1); -+ regmap_write(dsi2->regmap, DSI2_INT_MASK_IPI, 0x1); -+ regmap_write(dsi2->regmap, DSI2_INT_MASK_FIFO, 0x1); -+ regmap_write(dsi2->regmap, DSI2_INT_MASK_PRI, 0x1); -+ regmap_write(dsi2->regmap, DSI2_INT_MASK_CRI, 0x1); -+ } else { -+ regmap_write(dsi2->regmap, DSI2_INT_MASK_PHY, 0x0); -+ regmap_write(dsi2->regmap, DSI2_INT_MASK_TO, 0x0); -+ regmap_write(dsi2->regmap, DSI2_INT_MASK_ACK, 0x0); -+ regmap_write(dsi2->regmap, DSI2_INT_MASK_IPI, 0x0); -+ regmap_write(dsi2->regmap, DSI2_INT_MASK_FIFO, 0x0); -+ regmap_write(dsi2->regmap, DSI2_INT_MASK_PRI, 0x0); -+ regmap_write(dsi2->regmap, DSI2_INT_MASK_CRI, 0x0); -+ }; -+} -+ -+static void dw_mipi_dsi2_set_vid_mode(struct dw_mipi_dsi2 *dsi2) -+{ -+ u32 val = 0, mode; -+ int ret; -+ -+ if (dsi2->mode_flags & MIPI_DSI_MODE_VIDEO_NO_HFP) -+ val |= BLK_HFP_HS_EN; -+ -+ if (dsi2->mode_flags & MIPI_DSI_MODE_VIDEO_NO_HBP) -+ val |= BLK_HBP_HS_EN; -+ -+ if (dsi2->mode_flags & MIPI_DSI_MODE_VIDEO_NO_HSA) -+ val |= BLK_HSA_HS_EN; -+ -+ if (dsi2->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) -+ val |= VID_MODE_TYPE_BURST; -+ else if (dsi2->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) -+ val |= VID_MODE_TYPE_NON_BURST_SYNC_PULSES; -+ else -+ val |= VID_MODE_TYPE_NON_BURST_SYNC_EVENTS; -+ -+ regmap_write(dsi2->regmap, DSI2_DSI_VID_TX_CFG, val); -+ -+ regmap_write(dsi2->regmap, DSI2_MODE_CTRL, VIDEO_MODE); -+ ret = regmap_read_poll_timeout(dsi2->regmap, DSI2_MODE_STATUS, -+ mode, mode & VIDEO_MODE, -+ 1000, MODE_STATUS_TIMEOUT_US); -+ if (ret < 0) -+ dev_err(dsi2->dev, "failed to enter video mode\n"); -+} -+ -+static void dw_mipi_dsi2_set_data_stream_mode(struct dw_mipi_dsi2 *dsi2) -+{ -+ u32 mode; -+ int ret; -+ -+ regmap_write(dsi2->regmap, DSI2_MODE_CTRL, DATA_STREAM_MODE); -+ ret = regmap_read_poll_timeout(dsi2->regmap, DSI2_MODE_STATUS, -+ mode, mode & DATA_STREAM_MODE, -+ 1000, MODE_STATUS_TIMEOUT_US); -+ if (ret < 0) -+ dev_err(dsi2->dev, "failed to enter data stream mode\n"); -+} -+ -+static void dw_mipi_dsi2_set_cmd_mode(struct dw_mipi_dsi2 *dsi2) -+{ -+ u32 mode; -+ int ret; -+ -+ regmap_write(dsi2->regmap, DSI2_MODE_CTRL, COMMAND_MODE); -+ ret = regmap_read_poll_timeout(dsi2->regmap, DSI2_MODE_STATUS, -+ mode, mode & COMMAND_MODE, -+ 1000, MODE_STATUS_TIMEOUT_US); -+ if (ret < 0) -+ dev_err(dsi2->dev, "failed to enter data stream mode\n"); -+} -+ -+static void dw_mipi_dsi2_disable(struct dw_mipi_dsi2 *dsi2) -+{ -+ regmap_write(dsi2->regmap, DSI2_IPI_PIX_PKT_CFG, 0); -+ dw_mipi_dsi2_set_cmd_mode(dsi2); -+} -+ -+static void dw_mipi_dsi2_post_disable(struct dw_mipi_dsi2 *dsi2) -+{ -+ dw_mipi_dsi2_irq_enable(dsi2, 0); -+ regmap_write(dsi2->regmap, DSI2_PWR_UP, RESET); -+ phy_power_off(dsi2->dcphy); -+ pm_runtime_put(dsi2->dev); -+} -+ -+static void dw_mipi_dsi2_encoder_atomic_disable(struct drm_encoder *encoder, -+ struct drm_atomic_state *state) -+{ -+ struct dw_mipi_dsi2 *dsi2 = encoder_to_dsi2(encoder); -+ struct drm_crtc *crtc = encoder->crtc; -+ -+ if (dsi2->panel) -+ drm_panel_disable(dsi2->panel); -+ -+ dw_mipi_dsi2_disable(dsi2); -+ -+ if (dsi2->panel) -+ drm_panel_unprepare(dsi2->panel); -+ -+ dw_mipi_dsi2_post_disable(dsi2); -+ -+ if (!crtc->state->active_changed) -+ return; -+} -+ -+static void dw_mipi_dsi2_get_lane_rate(struct dw_mipi_dsi2 *dsi2) -+{ -+ struct device *dev = dsi2->dev; -+ const struct drm_display_mode *mode = &dsi2->mode; -+ u64 max_lane_rate; -+ u64 lane_rate, target_pclk; -+ u32 value; -+ int bpp, lanes; -+ u64 tmp; -+ -+ max_lane_rate = (dsi2->c_option) ? -+ dsi2->pdata->cphy_max_symbol_rate_per_lane : -+ dsi2->pdata->dphy_max_bit_rate_per_lane; -+ -+ lanes = dsi2->lanes; -+ bpp = mipi_dsi_pixel_format_to_bpp(dsi2->format); -+ if (bpp < 0) -+ bpp = 24; -+ -+ /* -+ * optional override of the desired bandwidth -+ * High-Speed mode: Differential and terminated: 80Mbps ~ 4500 Mbps. -+ */ -+ if (!of_property_read_u32(dev->of_node, "rockchip,lane-rate", &value)) { -+ if (value >= 80000 && value <= 4500000) -+ lane_rate = value * MSEC_PER_SEC; -+ else if (value >= 80 && value <= 4500) -+ lane_rate = value * USEC_PER_SEC; -+ else -+ lane_rate = 80 * USEC_PER_SEC; -+ } else { -+ tmp = (u64)mode->crtc_clock * 1000 * bpp; -+ do_div(tmp, lanes); -+ -+ /* -+ * Multiple bits are encoded into each symbol epoch, -+ * the data rate is ~2.28x the symbol rate. -+ */ -+ if (dsi2->c_option) -+ tmp = DIV_ROUND_CLOSEST_ULL(tmp * 100, 228); -+ -+ /* set BW a little larger only in video burst mode in -+ * consideration of the protocol overhead and HS mode -+ * switching to BLLP mode, take 1 / 0.9, since Mbps must -+ * big than bandwidth of RGB -+ */ -+ if (dsi2->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) { -+ tmp *= 10; -+ do_div(tmp, 9); -+ } -+ -+ if (tmp > max_lane_rate) -+ lane_rate = max_lane_rate; -+ else -+ lane_rate = tmp; -+ } -+ -+ target_pclk = DIV_ROUND_CLOSEST_ULL(lane_rate * lanes, bpp); -+ phy_mipi_dphy_get_default_config(target_pclk, bpp, lanes, -+ &dsi2->phy_opts.mipi_dphy); -+} -+ -+static void dw_mipi_dsi2_set_lane_rate(struct dw_mipi_dsi2 *dsi2) -+{ -+ unsigned long hs_clk_rate; -+ -+ if (dsi2->dcphy) -+ if (!dsi2->c_option) -+ phy_set_mode(dsi2->dcphy, PHY_MODE_MIPI_DPHY); -+ -+ phy_configure(dsi2->dcphy, &dsi2->phy_opts); -+ hs_clk_rate = dsi2->phy_opts.mipi_dphy.hs_clk_rate; -+ dsi2->lane_hs_rate = DIV_ROUND_UP(hs_clk_rate, MSEC_PER_SEC); -+} -+ -+static void dw_mipi_dsi2_host_softrst(struct dw_mipi_dsi2 *dsi2) -+{ -+ if (dsi2->apb_rst) { -+ reset_control_assert(dsi2->apb_rst); -+ usleep_range(10, 20); -+ reset_control_deassert(dsi2->apb_rst); -+ } -+ -+ regmap_write(dsi2->regmap, DSI2_SOFT_RESET, 0x0); -+ udelay(100); -+ regmap_write(dsi2->regmap, DSI2_SOFT_RESET, -+ SYS_RSTN | PHY_RSTN | IPI_RSTN); -+} -+ -+static void dw_mipi_dsi2_phy_mode_cfg(struct dw_mipi_dsi2 *dsi2) -+{ -+ u32 val = 0; -+ -+ /* PPI width is fixed to 16 bits in DCPHY */ -+ val |= PPI_WIDTH(PPI_WIDTH_16_BITS) | PHY_LANES(dsi2->lanes); -+ val |= PHY_TYPE(dsi2->c_option ? CPHY : DPHY); -+ regmap_write(dsi2->regmap, DSI2_PHY_MODE_CFG, val); -+} -+ -+static void dw_mipi_dsi2_phy_clk_mode_cfg(struct dw_mipi_dsi2 *dsi2) -+{ -+ u32 sys_clk, esc_clk_div; -+ u32 val = 0; -+ -+ /* -+ * clk_type should be NON_CONTINUOUS_CLK before -+ * initial deskew calibration be sent. -+ */ -+ val |= NON_CONTINUOUS_CLK; -+ -+ /* The maximum value of the escape clock frequency is 20MHz */ -+ sys_clk = clk_get_rate(dsi2->sys_clk) / USEC_PER_SEC; -+ esc_clk_div = DIV_ROUND_UP(sys_clk, 20 * 2); -+ val |= PHY_LPTX_CLK_DIV(esc_clk_div); -+ -+ regmap_write(dsi2->regmap, DSI2_PHY_CLK_CFG, val); -+} -+ -+static void dw_mipi_dsi2_phy_ratio_cfg(struct dw_mipi_dsi2 *dsi2) -+{ -+ struct drm_display_mode *mode = &dsi2->mode; -+ u64 sys_clk = clk_get_rate(dsi2->sys_clk); -+ u64 pixel_clk, ipi_clk, phy_hsclk; -+ u64 tmp; -+ -+ /* -+ * in DPHY mode, the phy_hstx_clk is exactly 1/16 the Lane high-speed -+ * data rate; In CPHY mode, the phy_hstx_clk is exactly 1/7 the trio -+ * high speed symbol rate. -+ */ -+ if (dsi2->c_option) -+ phy_hsclk = DIV_ROUND_CLOSEST_ULL(dsi2->lane_hs_rate * MSEC_PER_SEC, 7); -+ else -+ phy_hsclk = DIV_ROUND_CLOSEST_ULL(dsi2->lane_hs_rate * MSEC_PER_SEC, 16); -+ -+ /* IPI_RATIO_MAN_CFG = PHY_HSTX_CLK / IPI_CLK */ -+ pixel_clk = mode->crtc_clock * MSEC_PER_SEC; -+ ipi_clk = pixel_clk / 4; -+ -+ tmp = DIV_ROUND_CLOSEST_ULL(phy_hsclk << 16, ipi_clk); -+ regmap_write(dsi2->regmap, DSI2_PHY_IPI_RATIO_MAN_CFG, -+ PHY_IPI_RATIO(tmp)); -+ -+ /* -+ * SYS_RATIO_MAN_CFG = MIPI_DCPHY_HSCLK_Freq / MIPI_DCPHY_HSCLK_Freq -+ */ -+ tmp = DIV_ROUND_CLOSEST_ULL(phy_hsclk << 16, sys_clk); -+ regmap_write(dsi2->regmap, DSI2_PHY_SYS_RATIO_MAN_CFG, -+ PHY_SYS_RATIO(tmp)); -+} -+ -+static void dw_mipi_dsi2_lp2hs_or_hs2lp_cfg(struct dw_mipi_dsi2 *dsi2) -+{ -+ struct phy_configure_opts_mipi_dphy *cfg = &dsi2->phy_opts.mipi_dphy; -+ unsigned long long tmp, ui; -+ unsigned long long hstx_clk; -+ -+ hstx_clk = DIV_ROUND_CLOSEST_ULL(dsi2->lane_hs_rate * MSEC_PER_SEC, 16); -+ -+ ui = ALIGN(PSEC_PER_SEC, hstx_clk); -+ do_div(ui, hstx_clk); -+ -+ /* PHY_LP2HS_TIME = (TLPX + THS-PREPARE + THS-ZERO) / Tphy_hstx_clk */ -+ tmp = cfg->lpx + cfg->hs_prepare + cfg->hs_zero; -+ tmp = DIV_ROUND_CLOSEST_ULL(tmp << 16, ui); -+ regmap_write(dsi2->regmap, DSI2_PHY_LP2HS_MAN_CFG, PHY_LP2HS_TIME(tmp)); -+ -+ /* PHY_HS2LP_TIME = (THS-TRAIL + THS-EXIT) / Tphy_hstx_clk */ -+ tmp = cfg->hs_trail + cfg->hs_exit; -+ tmp = DIV_ROUND_CLOSEST_ULL(tmp << 16, ui); -+ regmap_write(dsi2->regmap, DSI2_PHY_HS2LP_MAN_CFG, PHY_HS2LP_TIME(tmp)); -+} -+ -+static void dw_mipi_dsi2_phy_init(struct dw_mipi_dsi2 *dsi2) -+{ -+ dw_mipi_dsi2_phy_mode_cfg(dsi2); -+ dw_mipi_dsi2_phy_clk_mode_cfg(dsi2); -+ dw_mipi_dsi2_phy_ratio_cfg(dsi2); -+ dw_mipi_dsi2_lp2hs_or_hs2lp_cfg(dsi2); -+ -+ /* phy configuration 8 - 10 */ -+} -+ -+static void dw_mipi_dsi2_tx_option_set(struct dw_mipi_dsi2 *dsi2) -+{ -+ u32 val; -+ -+ val = BTA_EN | EOTP_TX_EN; -+ -+ if (dsi2->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET) -+ val &= ~EOTP_TX_EN; -+ -+ regmap_write(dsi2->regmap, DSI2_DSI_GENERAL_CFG, val); -+ regmap_write(dsi2->regmap, DSI2_DSI_VCID_CFG, TX_VCID(dsi2->channel)); -+ -+ if (dsi2->scrambling_en) -+ regmap_write(dsi2->regmap, DSI2_DSI_SCRAMBLING_CFG, -+ SCRAMBLING_EN); -+} -+ -+static void dw_mipi_dsi2_ipi_color_coding_cfg(struct dw_mipi_dsi2 *dsi2) -+{ -+ u32 val, color_depth; -+ -+ switch (dsi2->format) { -+ case MIPI_DSI_FMT_RGB666: -+ case MIPI_DSI_FMT_RGB666_PACKED: -+ color_depth = IPI_DEPTH_6_BITS; -+ break; -+ case MIPI_DSI_FMT_RGB565: -+ color_depth = IPI_DEPTH_5_6_5_BITS; -+ break; -+ case MIPI_DSI_FMT_RGB888: -+ default: -+ color_depth = IPI_DEPTH_8_BITS; -+ break; -+ } -+ -+ val = IPI_DEPTH(color_depth) | -+ IPI_FORMAT(dsi2->dsc_enable ? IPI_FORMAT_DSC : IPI_FORMAT_RGB); -+ regmap_write(dsi2->regmap, DSI2_IPI_COLOR_MAN_CFG, val); -+ grf_field_write(dsi2, IPI_COLOR_DEPTH, color_depth); -+ -+ if (dsi2->dsc_enable) -+ grf_field_write(dsi2, IPI_FORMAT, IPI_FORMAT_DSC); -+} -+ -+static void dw_mipi_dsi2_ipi_set(struct dw_mipi_dsi2 *dsi2) -+{ -+ struct drm_display_mode *mode = &dsi2->mode; -+ u32 hline, hsa, hbp, hact; -+ u64 hline_time, hsa_time, hbp_time, hact_time, tmp; -+ u64 pixel_clk, phy_hs_clk; -+ u32 vact, vsa, vfp, vbp; -+ u16 val; -+ -+ val = mode->hdisplay; -+ -+ regmap_write(dsi2->regmap, DSI2_IPI_PIX_PKT_CFG, MAX_PIX_PKT(val)); -+ -+ dw_mipi_dsi2_ipi_color_coding_cfg(dsi2); -+ -+ /* -+ * if the controller is intended to operate in data stream mode, -+ * no more steps are required. -+ */ -+ if (!(dsi2->mode_flags & MIPI_DSI_MODE_VIDEO)) -+ return; -+ -+ vact = mode->vdisplay; -+ vsa = mode->vsync_end - mode->vsync_start; -+ vfp = mode->vsync_start - mode->vdisplay; -+ vbp = mode->vtotal - mode->vsync_end; -+ hact = mode->hdisplay; -+ hsa = mode->hsync_end - mode->hsync_start; -+ hbp = mode->htotal - mode->hsync_end; -+ hline = mode->htotal; -+ -+ pixel_clk = mode->crtc_clock * MSEC_PER_SEC; -+ -+ if (dsi2->c_option) -+ phy_hs_clk = DIV_ROUND_CLOSEST_ULL(dsi2->lane_hs_rate * MSEC_PER_SEC, 7); -+ else -+ phy_hs_clk = DIV_ROUND_CLOSEST_ULL(dsi2->lane_hs_rate * MSEC_PER_SEC, 16); -+ -+ tmp = hsa * phy_hs_clk; -+ hsa_time = DIV_ROUND_CLOSEST_ULL(tmp << 16, pixel_clk); -+ regmap_write(dsi2->regmap, DSI2_IPI_VID_HSA_MAN_CFG, -+ VID_HSA_TIME(hsa_time)); -+ -+ tmp = hbp * phy_hs_clk; -+ hbp_time = DIV_ROUND_CLOSEST_ULL(tmp << 16, pixel_clk); -+ regmap_write(dsi2->regmap, DSI2_IPI_VID_HBP_MAN_CFG, -+ VID_HBP_TIME(hbp_time)); -+ -+ tmp = hact * phy_hs_clk; -+ hact_time = DIV_ROUND_CLOSEST_ULL(tmp << 16, pixel_clk); -+ regmap_write(dsi2->regmap, DSI2_IPI_VID_HACT_MAN_CFG, -+ VID_HACT_TIME(hact_time)); -+ -+ tmp = hline * phy_hs_clk; -+ hline_time = DIV_ROUND_CLOSEST_ULL(tmp << 16, pixel_clk); -+ regmap_write(dsi2->regmap, DSI2_IPI_VID_HLINE_MAN_CFG, -+ VID_HLINE_TIME(hline_time)); -+ -+ regmap_write(dsi2->regmap, DSI2_IPI_VID_VSA_MAN_CFG, -+ VID_VSA_LINES(vsa)); -+ regmap_write(dsi2->regmap, DSI2_IPI_VID_VBP_MAN_CFG, -+ VID_VBP_LINES(vbp)); -+ regmap_write(dsi2->regmap, DSI2_IPI_VID_VACT_MAN_CFG, -+ VID_VACT_LINES(vact)); -+ regmap_write(dsi2->regmap, DSI2_IPI_VID_VFP_MAN_CFG, -+ VID_VFP_LINES(vfp)); -+} -+ -+static void -+dw_mipi_dsi2_work_mode(struct dw_mipi_dsi2 *dsi2, u32 mode) -+{ -+ /* -+ * select controller work in Manual mode -+ * Manual: MANUAL_MODE_EN -+ * Automatic: 0 -+ */ -+ regmap_write(dsi2->regmap, MANUAL_MODE_CFG, mode); -+} -+ -+static void dw_mipi_dsi2_pre_enable(struct dw_mipi_dsi2 *dsi2) -+{ -+ pm_runtime_get_sync(dsi2->dev); -+ -+ dw_mipi_dsi2_host_softrst(dsi2); -+ regmap_write(dsi2->regmap, DSI2_PWR_UP, RESET); -+ -+ /* there may be some timeout registers may be configured if desired */ -+ -+ dw_mipi_dsi2_work_mode(dsi2, MANUAL_MODE_EN); -+ dw_mipi_dsi2_phy_init(dsi2); -+ dw_mipi_dsi2_tx_option_set(dsi2); -+ dw_mipi_dsi2_irq_enable(dsi2, 1); -+ phy_power_on(dsi2->dcphy); -+ -+ /* -+ * initial deskew calibration is send after phy_power_on, -+ * then we can configure clk_type. -+ */ -+ if (!(dsi2->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)) -+ regmap_update_bits(dsi2->regmap, DSI2_PHY_CLK_CFG, -+ CLK_TYPE_MASK, CONTIUOUS_CLK); -+ -+ regmap_write(dsi2->regmap, DSI2_PWR_UP, POWER_UP); -+ dw_mipi_dsi2_set_cmd_mode(dsi2); -+} -+ -+static void dw_mipi_dsi2_enable(struct dw_mipi_dsi2 *dsi2) -+{ -+ dw_mipi_dsi2_ipi_set(dsi2); -+ -+ if (dsi2->mode_flags & MIPI_DSI_MODE_VIDEO) -+ dw_mipi_dsi2_set_vid_mode(dsi2); -+ else -+ dw_mipi_dsi2_set_data_stream_mode(dsi2); -+} -+ -+static int dw_mipi_dsi2_encoder_mode_set(struct dw_mipi_dsi2 *dsi2, -+ struct drm_atomic_state *state) -+{ -+ struct drm_encoder *encoder = &dsi2->encoder.encoder; -+ struct drm_connector *connector; -+ struct drm_connector_state *conn_state; -+ struct drm_crtc_state *crtc_state; -+ const struct drm_display_mode *adjusted_mode; -+ struct drm_display_mode *mode = &dsi2->mode; -+ -+ connector = drm_atomic_get_new_connector_for_encoder(state, encoder); -+ if (!connector) -+ return -ENODEV; -+ -+ conn_state = drm_atomic_get_new_connector_state(state, connector); -+ if (!conn_state) -+ return -ENODEV; -+ -+ crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc); -+ if (!crtc_state) { -+ dev_err(dsi2->dev, "failed to get crtc state\n"); -+ return -ENODEV; -+ } -+ -+ adjusted_mode = &crtc_state->adjusted_mode; -+ drm_mode_copy(mode, adjusted_mode); -+ -+ return 0; -+} -+ -+static void dw_mipi_dsi2_encoder_atomic_enable(struct drm_encoder *encoder, -+ struct drm_atomic_state *state) -+{ -+ struct dw_mipi_dsi2 *dsi2 = encoder_to_dsi2(encoder); -+ int ret; -+ -+ ret = dw_mipi_dsi2_encoder_mode_set(dsi2, state); -+ if (ret) { -+ dev_err(dsi2->dev, "failed to set dsi2 mode\n"); -+ return; -+ } -+ -+ dw_mipi_dsi2_get_lane_rate(dsi2); -+ -+ if (dsi2->dcphy) -+ dw_mipi_dsi2_set_lane_rate(dsi2); -+ -+ dw_mipi_dsi2_pre_enable(dsi2); -+ -+ if (dsi2->panel) -+ drm_panel_prepare(dsi2->panel); -+ -+ dw_mipi_dsi2_enable(dsi2); -+ -+ if (dsi2->panel) -+ drm_panel_enable(dsi2->panel); -+ -+ DRM_DEV_INFO(dsi2->dev, "final DSI-Link bandwidth: %u x %d %s\n", -+ dsi2->lane_hs_rate, -+ dsi2->lanes, -+ dsi2->c_option ? "Ksps" : "Kbps"); -+} -+ -+static int -+dw_mipi_dsi2_encoder_atomic_check(struct drm_encoder *encoder, -+ struct drm_crtc_state *crtc_state, -+ struct drm_connector_state *conn_state) -+{ -+ -+ struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state); -+ struct dw_mipi_dsi2 *dsi2 = encoder_to_dsi2(encoder); -+ struct drm_connector *connector = conn_state->connector; -+ struct drm_display_info *info = &connector->display_info; -+ -+ switch (dsi2->format) { -+ case MIPI_DSI_FMT_RGB888: -+ s->output_mode = ROCKCHIP_OUT_MODE_P888; -+ break; -+ case MIPI_DSI_FMT_RGB666: -+ s->output_mode = ROCKCHIP_OUT_MODE_P666; -+ break; -+ case MIPI_DSI_FMT_RGB565: -+ s->output_mode = ROCKCHIP_OUT_MODE_P565; -+ break; -+ default: -+ WARN_ON(1); -+ return -EINVAL; -+ } -+ -+ if (info->num_bus_formats) -+ s->bus_format = info->bus_formats[0]; -+ else -+ s->bus_format = MEDIA_BUS_FMT_RGB888_1X24; -+ -+ s->output_type = DRM_MODE_CONNECTOR_DSI; -+ s->bus_flags = info->bus_flags; -+ s->color_space = V4L2_COLORSPACE_DEFAULT; -+ -+ return 0; -+} -+ -+static const struct drm_encoder_helper_funcs -+dw_mipi_dsi2_encoder_helper_funcs = { -+ .atomic_enable = dw_mipi_dsi2_encoder_atomic_enable, -+ .atomic_disable = dw_mipi_dsi2_encoder_atomic_disable, -+ .atomic_check = dw_mipi_dsi2_encoder_atomic_check, -+}; -+ -+static int dw_mipi_dsi2_connector_get_modes(struct drm_connector *connector) -+{ -+ struct dw_mipi_dsi2 *dsi2 = con_to_dsi2(connector); -+ -+ if (dsi2->bridge && (dsi2->bridge->ops & DRM_BRIDGE_OP_MODES)) -+ return drm_bridge_get_modes(dsi2->bridge, connector); -+ -+ if (dsi2->panel) -+ return drm_panel_get_modes(dsi2->panel, connector); -+ -+ return -EINVAL; -+} -+ -+static enum drm_mode_status -+dw_mipi_dsi2_connector_mode_valid(struct drm_connector *connector, -+ struct drm_display_mode *mode) -+{ -+ struct videomode vm; -+ u8 min_pixels = 4; -+ -+ drm_display_mode_to_videomode(mode, &vm); -+ -+ if (vm.vactive > 16383) -+ return MODE_VIRTUAL_Y; -+ -+ if (vm.vsync_len > 1023) -+ return MODE_VSYNC_WIDE; -+ -+ if (vm.vback_porch > 1023 || vm.vfront_porch > 1023) -+ return MODE_VBLANK_WIDE; -+ -+ /* -+ * the minimum region size (HSA,HBP,HACT,HFP) is 4 pixels -+ * which is the ip known issues and limitations. -+ */ -+ if (!(vm.hsync_len < min_pixels || vm.hback_porch < min_pixels || -+ vm.hfront_porch < min_pixels || vm.hactive < min_pixels)) -+ return MODE_OK; -+ -+ if (vm.hsync_len < min_pixels) -+ vm.hsync_len = min_pixels; -+ -+ if (vm.hback_porch < min_pixels) -+ vm.hback_porch = min_pixels; -+ -+ if (vm.hfront_porch < min_pixels) -+ vm.hfront_porch = min_pixels; -+ -+ if (vm.hactive < min_pixels) -+ vm.hactive = min_pixels; -+ -+ drm_display_mode_from_videomode(&vm, mode); -+ -+ return MODE_OK; -+} -+ -+static struct drm_connector_helper_funcs dw_mipi_dsi2_connector_helper_funcs = { -+ .get_modes = dw_mipi_dsi2_connector_get_modes, -+ .mode_valid = dw_mipi_dsi2_connector_mode_valid, -+}; -+ -+static enum drm_connector_status -+dw_mipi_dsi2_connector_detect(struct drm_connector *connector, bool force) -+{ -+ struct dw_mipi_dsi2 *dsi2 = con_to_dsi2(connector); -+ -+ if (dsi2->bridge && (dsi2->bridge->ops & DRM_BRIDGE_OP_DETECT)) -+ return drm_bridge_detect(dsi2->bridge); -+ -+ return connector_status_connected; -+} -+ -+static void dw_mipi_dsi2_drm_connector_destroy(struct drm_connector *connector) -+{ -+ drm_connector_unregister(connector); -+ drm_connector_cleanup(connector); -+} -+ -+static const struct drm_connector_funcs dw_mipi_dsi2_atomic_connector_funcs = { -+ .fill_modes = drm_helper_probe_single_connector_modes, -+ .detect = dw_mipi_dsi2_connector_detect, -+ .destroy = dw_mipi_dsi2_drm_connector_destroy, -+ .reset = drm_atomic_helper_connector_reset, -+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, -+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, -+}; -+ -+static int dw_mipi_dsi2_get_dsc_params_from_sink(struct dw_mipi_dsi2 *dsi2, -+ struct drm_panel *panel, -+ struct drm_bridge *bridge) -+{ -+ struct drm_dsc_picture_parameter_set *pps = NULL; -+ struct device_node *np = NULL; -+ struct cmd_header *header; -+ const void *data; -+ char *d; -+ uint8_t *dsc_packed_pps; -+ int len; -+ -+ if (!panel && !bridge) -+ return -ENODEV; -+ -+ if (panel) -+ np = panel->dev->of_node; -+ else -+ np = bridge->of_node; -+ -+ dsi2->c_option = of_property_read_bool(np, "phy-c-option"); -+ dsi2->scrambling_en = of_property_read_bool(np, "scrambling-enable"); -+ dsi2->dsc_enable = of_property_read_bool(np, "compressed-data"); -+ -+ if (!dsi2->dsc_enable) -+ return 0; -+ -+ data = of_get_property(np, "panel-init-sequence", &len); -+ if (!data) -+ return -EINVAL; -+ -+ d = devm_kmemdup(dsi2->dev, data, len, GFP_KERNEL); -+ if (!d) -+ return -ENOMEM; -+ -+ while (len > sizeof(*header)) { -+ header = (struct cmd_header *)d; -+ d += sizeof(*header); -+ len -= sizeof(*header); -+ -+ if (header->payload_length > len) -+ return -EINVAL; -+ -+ if (header->cmd_type == MIPI_DSI_PICTURE_PARAMETER_SET) { -+ dsc_packed_pps = devm_kmemdup(dsi2->dev, d, -+ header->payload_length, GFP_KERNEL); -+ if (!dsc_packed_pps) -+ return -ENOMEM; -+ -+ pps = (struct drm_dsc_picture_parameter_set *)dsc_packed_pps; -+ break; -+ } -+ -+ d += header->payload_length; -+ len -= header->payload_length; -+ } -+ -+ if (!pps) { -+ dev_err(dsi2->dev, "not found dsc pps definition\n"); -+ return -EINVAL; -+ } -+ -+ dsi2->pps = pps; -+ -+ return 0; -+} -+ -+static int dw_mipi_dsi2_connector_init(struct dw_mipi_dsi2 *dsi2) -+{ -+ struct drm_encoder *encoder = &dsi2->encoder.encoder; -+ struct drm_connector *connector = &dsi2->connector; -+ struct drm_device *drm_dev = dsi2->drm_dev; -+ struct device *dev = dsi2->dev; -+ int ret; -+ -+ ret = drm_connector_init(drm_dev, connector, -+ &dw_mipi_dsi2_atomic_connector_funcs, -+ DRM_MODE_CONNECTOR_DSI); -+ if (ret) { -+ DRM_DEV_ERROR(dev, "Failed to initialize connector\n"); -+ return ret; -+ } -+ -+ drm_connector_helper_add(connector, -+ &dw_mipi_dsi2_connector_helper_funcs); -+ ret = drm_connector_attach_encoder(connector, encoder); -+ if (ret < 0) { -+ DRM_DEV_ERROR(dev, "Failed to attach encoder: %d\n", ret); -+ goto connector_cleanup; -+ } -+ -+ return 0; -+ -+connector_cleanup: -+ connector->funcs->destroy(connector); -+ -+ return ret; -+} -+ -+static int dw_mipi_dsi2_bind(struct device *dev, struct device *master, -+ void *data) -+{ -+ struct dw_mipi_dsi2 *dsi2 = dev_get_drvdata(dev); -+ struct drm_device *drm_dev = data; -+ struct drm_encoder *encoder = &dsi2->encoder.encoder; -+ struct device_node *of_node = dsi2->dev->of_node; -+ struct drm_connector *connector = NULL; -+ enum drm_bridge_attach_flags flags; -+ int ret; -+ -+ dsi2->drm_dev = drm_dev; -+ -+ ret = drm_of_find_panel_or_bridge(dev->of_node, 1, -1, -+ &dsi2->panel, &dsi2->bridge); -+ if (ret) { -+ DRM_DEV_ERROR(dev, "Failed to find panel or bridge: %d\n", ret); -+ return ret; -+ } -+ -+ dw_mipi_dsi2_get_dsc_params_from_sink(dsi2, dsi2->panel, dsi2->bridge); -+ encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev, of_node); -+ -+ ret = drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_DSI); -+ if (ret) { -+ DRM_ERROR("Failed to initialize encoder with drm\n"); -+ return ret; -+ } -+ -+ drm_encoder_helper_add(encoder, &dw_mipi_dsi2_encoder_helper_funcs); -+ -+ rockchip_drm_encoder_set_crtc_endpoint_id(&dsi2->encoder, -+ dev->of_node, 0, 0); -+ -+ if (dsi2->bridge) { -+ struct list_head *connector_list = -+ &drm_dev->mode_config.connector_list; -+ -+ dsi2->bridge->driver_private = &dsi2->host; -+ dsi2->bridge->encoder = encoder; -+ -+ flags = dsi2->bridge->ops & DRM_BRIDGE_OP_MODES ? -+ DRM_BRIDGE_ATTACH_NO_CONNECTOR : 0; -+ ret = drm_bridge_attach(encoder, dsi2->bridge, NULL, flags); -+ if (ret) { -+ DRM_DEV_ERROR(dev, -+ "Failed to attach bridge: %d\n", ret); -+ goto encoder_cleanup; -+ } -+ -+ if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) -+ list_for_each_entry(connector, connector_list, head) -+ if (drm_connector_has_possible_encoder(connector, -+ encoder)) -+ break; -+ } -+ -+ if (dsi2->panel || (dsi2->bridge && (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR))) { -+ ret = dw_mipi_dsi2_connector_init(dsi2); -+ if (ret) -+ goto encoder_cleanup; -+ -+ connector = &dsi2->connector; -+ } -+ -+ pm_runtime_enable(dsi2->dev); -+ -+ return 0; -+ -+encoder_cleanup: -+ encoder->funcs->destroy(encoder); -+ -+ return ret; -+} -+ -+static void dw_mipi_dsi2_unbind(struct device *dev, struct device *master, -+ void *data) -+{ -+ struct dw_mipi_dsi2 *dsi2 = dev_get_drvdata(dev); -+ -+ pm_runtime_disable(dsi2->dev); -+ dsi2->encoder.encoder.funcs->destroy(&dsi2->encoder.encoder); -+} -+ -+static const struct component_ops dw_mipi_dsi2_ops = { -+ .bind = dw_mipi_dsi2_bind, -+ .unbind = dw_mipi_dsi2_unbind, -+}; -+ -+struct dsi2_irq_data { -+ u32 offeset; -+ char *irq_src; -+}; -+ -+static const struct dsi2_irq_data dw_mipi_dsi2_irq_data[] = { -+ {DSI2_INT_ST_PHY, "int_st_phy"}, -+ {DSI2_INT_ST_TO, "int_st_to"}, -+ {DSI2_INT_ST_ACK, "int_st_ack"}, -+ {DSI2_INT_ST_IPI, "int_st_ipi"}, -+ {DSI2_INT_ST_FIFO, "int_st_fifo"}, -+ {DSI2_INT_ST_PRI, "int_st_pri"}, -+ {DSI2_INT_ST_CRI, "int_st_cri"}, -+}; -+ -+static irqreturn_t dw_mipi_dsi2_irq_handler(int irq, void *dev_id) -+{ -+ -+ struct dw_mipi_dsi2 *dsi2 = dev_id; -+ u32 int_st; -+ unsigned int i; -+ -+ regmap_read(dsi2->regmap, INT_ST_MAIN, &int_st); -+ -+ for (i = 0; i < ARRAY_SIZE(dw_mipi_dsi2_irq_data); i++) -+ if (int_st & BIT(i)) -+ DRM_DEV_DEBUG(dsi2->dev, "%s\n", -+ dw_mipi_dsi2_irq_data[i].irq_src); -+ -+ return IRQ_HANDLED; -+} -+ -+static const struct regmap_config dw_mipi_dsi2_regmap_config = { -+ .name = "host", -+ .reg_bits = 32, -+ .val_bits = 32, -+ .reg_stride = 4, -+ .fast_io = true, -+ .max_register = DSI2_MAX_REGISGER, -+}; -+ -+static int dw_mipi_dsi2_host_attach(struct mipi_dsi_host *host, -+ struct mipi_dsi_device *device) -+{ -+ struct dw_mipi_dsi2 *dsi2 = host_to_dsi2(host); -+ -+ if (device->lanes < 1 || device->lanes > 8) -+ return -EINVAL; -+ -+ dsi2->client = device->dev.of_node; -+ dsi2->lanes = device->lanes; -+ dsi2->channel = device->channel; -+ dsi2->format = device->format; -+ dsi2->mode_flags = device->mode_flags; -+ -+ return 0; -+} -+ -+static int dw_mipi_dsi2_host_detach(struct mipi_dsi_host *host, -+ struct mipi_dsi_device *device) -+{ -+ return 0; -+} -+ -+static int dw_mipi_dsi2_read_from_fifo(struct dw_mipi_dsi2 *dsi2, -+ const struct mipi_dsi_msg *msg) -+{ -+ u8 *payload = msg->rx_buf; -+ u8 data_type; -+ u16 wc; -+ int i, j, ret, len = msg->rx_len; -+ unsigned int vrefresh = drm_mode_vrefresh(&dsi2->mode); -+ u32 val; -+ -+ ret = regmap_read_poll_timeout(dsi2->regmap, DSI2_CORE_STATUS, -+ val, val & CRI_RD_DATA_AVAIL, -+ 0, DIV_ROUND_UP(1000000, vrefresh)); -+ if (ret) { -+ DRM_DEV_ERROR(dsi2->dev, "CRI has no available read data\n"); -+ return ret; -+ } -+ -+ regmap_read(dsi2->regmap, DSI2_CRI_RX_HDR, &val); -+ data_type = val & 0x3f; -+ -+ if (mipi_dsi_packet_format_is_short(data_type)) { -+ for (i = 0; i < len && i < 2; i++) -+ payload[i] = (val >> (8 * (i + 1))) & 0xff; -+ -+ return 0; -+ } -+ -+ wc = (val >> 8) & 0xffff; -+ /* Receive payload */ -+ for (i = 0; i < len && i < wc; i += 4) { -+ regmap_read(dsi2->regmap, DSI2_CRI_RX_PLD, &val); -+ for (j = 0; j < 4 && j + i < len && j + i < wc; j++) -+ payload[i + j] = val >> (8 * j); -+ } -+ -+ return 0; -+} -+ -+static ssize_t dw_mipi_dsi2_transfer(struct dw_mipi_dsi2 *dsi2, -+ const struct mipi_dsi_msg *msg) -+{ -+ struct mipi_dsi_packet packet; -+ int ret; -+ u32 val; -+ u32 mode; -+ -+ regmap_update_bits(dsi2->regmap, DSI2_DSI_VID_TX_CFG, -+ LPDT_DISPLAY_CMD_EN, -+ msg->flags & MIPI_DSI_MSG_USE_LPM ? -+ LPDT_DISPLAY_CMD_EN : 0); -+ -+ /* create a packet to the DSI protocol */ -+ ret = mipi_dsi_create_packet(&packet, msg); -+ if (ret) { -+ DRM_DEV_ERROR(dsi2->dev, "failed to create packet: %d\n", ret); -+ return ret; -+ } -+ -+ ret = cri_fifos_wait_avail(dsi2); -+ if (ret) -+ return ret; -+ -+ /* Send payload */ -+ while (DIV_ROUND_UP(packet.payload_length, 4)) { -+ /* check cri interface is not busy */ -+ if (packet.payload_length < 4) { -+ /* send residu payload */ -+ val = 0; -+ memcpy(&val, packet.payload, packet.payload_length); -+ regmap_write(dsi2->regmap, DSI2_CRI_TX_PLD, val); -+ packet.payload_length = 0; -+ } else { -+ val = get_unaligned_le32(packet.payload); -+ regmap_write(dsi2->regmap, DSI2_CRI_TX_PLD, val); -+ packet.payload += 4; -+ packet.payload_length -= 4; -+ } -+ } -+ -+ /* Send packet header */ -+ mode = CMD_TX_MODE(msg->flags & MIPI_DSI_MSG_USE_LPM ? 1 : 0); -+ val = get_unaligned_le32(packet.header); -+ -+ regmap_write(dsi2->regmap, DSI2_CRI_TX_HDR, mode | val); -+ -+ ret = cri_fifos_wait_avail(dsi2); -+ if (ret) -+ return ret; -+ -+ if (msg->rx_len) { -+ ret = dw_mipi_dsi2_read_from_fifo(dsi2, msg); -+ if (ret < 0) -+ return ret; -+ } -+ -+ return msg->tx_len; -+} -+ -+static ssize_t dw_mipi_dsi2_host_transfer(struct mipi_dsi_host *host, -+ const struct mipi_dsi_msg *msg) -+{ -+ struct dw_mipi_dsi2 *dsi2 = host_to_dsi2(host); -+ -+ return dw_mipi_dsi2_transfer(dsi2, msg); -+} -+ -+static const struct mipi_dsi_host_ops dw_mipi_dsi2_host_ops = { -+ .attach = dw_mipi_dsi2_host_attach, -+ .detach = dw_mipi_dsi2_host_detach, -+ .transfer = dw_mipi_dsi2_host_transfer, -+}; -+ -+static int dw_mipi_dsi2_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct dw_mipi_dsi2 *dsi2; -+ struct resource *res; -+ void __iomem *regs; -+ int id; -+ int ret; -+ -+ dsi2 = devm_kzalloc(dev, sizeof(*dsi2), GFP_KERNEL); -+ if (!dsi2) -+ return -ENOMEM; -+ -+ id = of_alias_get_id(dev->of_node, "dsi"); -+ if (id < 0) -+ id = 0; -+ -+ dsi2->dev = dev; -+ dsi2->id = id; -+ dsi2->pdata = of_device_get_match_data(dev); -+ platform_set_drvdata(pdev, dsi2); -+ -+ if (device_property_read_bool(dev, "disable-hold-mode")) -+ dsi2->disable_hold_mode = true; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ regs = devm_ioremap_resource(dev, res); -+ if (IS_ERR(regs)) -+ return PTR_ERR(regs); -+ -+ dsi2->irq = platform_get_irq(pdev, 0); -+ if (dsi2->irq < 0) -+ return dsi2->irq; -+ -+ dsi2->pclk = devm_clk_get(dev, "pclk"); -+ if (IS_ERR(dsi2->pclk)) { -+ ret = PTR_ERR(dsi2->pclk); -+ DRM_DEV_ERROR(dev, "Unable to get pclk: %d\n", ret); -+ return ret; -+ } -+ -+ dsi2->sys_clk = devm_clk_get(dev, "sys_clk"); -+ if (IS_ERR(dsi2->sys_clk)) { -+ ret = PTR_ERR(dsi2->sys_clk); -+ DRM_DEV_ERROR(dev, "Unable to get sys_clk: %d\n", ret); -+ return ret; -+ } -+ -+ dsi2->regmap = devm_regmap_init_mmio(dev, regs, -+ &dw_mipi_dsi2_regmap_config); -+ if (IS_ERR(dsi2->regmap)) { -+ ret = PTR_ERR(dsi2->regmap); -+ DRM_DEV_ERROR(dev, "failed to init register map: %d\n", ret); -+ return ret; -+ } -+ -+ dsi2->grf = syscon_regmap_lookup_by_phandle(dev->of_node, -+ "rockchip,grf"); -+ if (IS_ERR(dsi2->grf)) { -+ ret = PTR_ERR(dsi2->grf); -+ DRM_DEV_ERROR(dsi2->dev, "Unable to get grf: %d\n", ret); -+ return ret; -+ } -+ -+ dsi2->apb_rst = devm_reset_control_get(dev, "apb"); -+ if (IS_ERR(dsi2->apb_rst)) { -+ ret = PTR_ERR(dsi2->apb_rst); -+ DRM_DEV_ERROR(dev, -+ "Unable to get reset control: %d\n", ret); -+ return ret; -+ } -+ -+ dsi2->dcphy = devm_phy_optional_get(dev, "dcphy"); -+ if (IS_ERR(dsi2->dcphy)) { -+ ret = PTR_ERR(dsi2->dcphy); -+ DRM_DEV_ERROR(dev, "failed to get mipi dcphy: %d\n", ret); -+ return ret; -+ } -+ -+ ret = devm_request_irq(dev, dsi2->irq, dw_mipi_dsi2_irq_handler, -+ IRQF_SHARED, dev_name(dev), dsi2); -+ if (ret) { -+ DRM_DEV_ERROR(dev, "failed to request irq: %d\n", ret); -+ return ret; -+ } -+ -+ dsi2->host.ops = &dw_mipi_dsi2_host_ops; -+ dsi2->host.dev = dev; -+ ret = mipi_dsi_host_register(&dsi2->host); -+ if (ret) { -+ DRM_DEV_ERROR(dev, "Failed to register MIPI host: %d\n", ret); -+ return ret; -+ } -+ -+ ret = component_add(&pdev->dev, &dw_mipi_dsi2_ops); -+ if (ret) -+ mipi_dsi_host_unregister(&dsi2->host); -+ -+ return ret; -+} -+ -+static void dw_mipi_dsi2_remove(struct platform_device *pdev) -+{ -+ struct dw_mipi_dsi2 *dsi2 = platform_get_drvdata(pdev); -+ -+ component_del(&pdev->dev, &dw_mipi_dsi2_ops); -+ mipi_dsi_host_unregister(&dsi2->host); -+} -+ -+static __maybe_unused int dw_mipi_dsi2_runtime_suspend(struct device *dev) -+{ -+ struct dw_mipi_dsi2 *dsi2 = dev_get_drvdata(dev); -+ -+ clk_disable_unprepare(dsi2->pclk); -+ clk_disable_unprepare(dsi2->sys_clk); -+ -+ return 0; -+} -+ -+static __maybe_unused int dw_mipi_dsi2_runtime_resume(struct device *dev) -+{ -+ struct dw_mipi_dsi2 *dsi2 = dev_get_drvdata(dev); -+ -+ clk_prepare_enable(dsi2->pclk); -+ clk_prepare_enable(dsi2->sys_clk); -+ -+ return 0; -+} -+ -+static const struct dev_pm_ops dw_mipi_dsi2_rockchip_pm_ops = { -+ SET_RUNTIME_PM_OPS(dw_mipi_dsi2_runtime_suspend, -+ dw_mipi_dsi2_runtime_resume, NULL) -+}; -+ -+static const u32 rk3588_dsi0_grf_reg_fields[MAX_FIELDS] = { -+ [TXREQCLKHS_EN] = GRF_REG_FIELD(0x0000, 11, 11), -+ [GATING_EN] = GRF_REG_FIELD(0x0000, 10, 10), -+ [IPI_SHUTDN] = GRF_REG_FIELD(0x0000, 9, 9), -+ [IPI_COLORM] = GRF_REG_FIELD(0x0000, 8, 8), -+ [IPI_COLOR_DEPTH] = GRF_REG_FIELD(0x0000, 4, 7), -+ [IPI_FORMAT] = GRF_REG_FIELD(0x0000, 0, 3), -+}; -+ -+static const u32 rk3588_dsi1_grf_reg_fields[MAX_FIELDS] = { -+ [TXREQCLKHS_EN] = GRF_REG_FIELD(0x0004, 11, 11), -+ [GATING_EN] = GRF_REG_FIELD(0x0004, 10, 10), -+ [IPI_SHUTDN] = GRF_REG_FIELD(0x0004, 9, 9), -+ [IPI_COLORM] = GRF_REG_FIELD(0x0004, 8, 8), -+ [IPI_COLOR_DEPTH] = GRF_REG_FIELD(0x0004, 4, 7), -+ [IPI_FORMAT] = GRF_REG_FIELD(0x0004, 0, 3), -+}; -+ -+static const struct dw_mipi_dsi2_plat_data rk3588_mipi_dsi2_plat_data = { -+ .dsi0_grf_reg_fields = rk3588_dsi0_grf_reg_fields, -+ .dsi1_grf_reg_fields = rk3588_dsi1_grf_reg_fields, -+ .dphy_max_bit_rate_per_lane = 4500000000ULL, -+ .cphy_max_symbol_rate_per_lane = 2000000000ULL, -+}; -+ -+static const struct of_device_id dw_mipi_dsi2_dt_ids[] = { -+ { -+ .compatible = "rockchip,rk3588-mipi-dsi2", -+ .data = &rk3588_mipi_dsi2_plat_data, -+ }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, dw_mipi_dsi2_dt_ids); -+ -+struct platform_driver dw_mipi_dsi2_rockchip_driver = { -+ .probe = dw_mipi_dsi2_probe, -+ .remove = dw_mipi_dsi2_remove, -+ .driver = { -+ .of_match_table = dw_mipi_dsi2_dt_ids, -+ .pm = &dw_mipi_dsi2_rockchip_pm_ops, -+ .name = "dw-mipi-dsi2", -+ }, -+}; -diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c -index 3ec8ff5..5024ba3 100644 ---- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c -+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c -@@ -507,6 +507,8 @@ static int __init rockchip_drm_init(void) - CONFIG_ROCKCHIP_DW_HDMI_QP); - ADD_ROCKCHIP_SUB_DRIVER(dw_mipi_dsi_rockchip_driver, - CONFIG_ROCKCHIP_DW_MIPI_DSI); -+ ADD_ROCKCHIP_SUB_DRIVER(dw_mipi_dsi2_rockchip_driver, -+ CONFIG_ROCKCHIP_DW_MIPI_DSI); - ADD_ROCKCHIP_SUB_DRIVER(inno_hdmi_driver, CONFIG_ROCKCHIP_INNO_HDMI); - ADD_ROCKCHIP_SUB_DRIVER(rk3066_hdmi_driver, - CONFIG_ROCKCHIP_RK3066_HDMI); -diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h -index d7f2f0f..d49e93f 100644 ---- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h -+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h -@@ -89,6 +89,7 @@ extern struct platform_driver cdn_dp_driver; - extern struct platform_driver dw_hdmi_rockchip_pltfm_driver; - extern struct platform_driver dw_hdmi_qp_rockchip_pltfm_driver; - extern struct platform_driver dw_mipi_dsi_rockchip_driver; -+extern struct platform_driver dw_mipi_dsi2_rockchip_driver; - extern struct platform_driver inno_hdmi_driver; - extern struct platform_driver rockchip_dp_driver; - extern struct platform_driver rockchip_lvds_driver; -diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig -index 4902633..e0be883 100644 ---- a/drivers/phy/rockchip/Kconfig -+++ b/drivers/phy/rockchip/Kconfig -@@ -83,6 +83,18 @@ config PHY_ROCKCHIP_PCIE - help - Enable this to support the Rockchip PCIe PHY. - -+config PHY_ROCKCHIP_SAMSUNG_DCPHY -+ tristate "Rockchip Samsung MIPI DCPHY driver" -+ depends on (ARCH_ROCKCHIP || COMPILE_TEST) -+ select GENERIC_PHY -+ select GENERIC_PHY_MIPI_DPHY -+ help -+ Enable this to support the Rockchip MIPI DCPHY with -+ Samsung IP block. -+ -+ To compile this driver as a module, choose M here: the module -+ will be called phy-rockchip-samsung-dcphy -+ - config PHY_ROCKCHIP_SAMSUNG_HDPTX - tristate "Rockchip Samsung HDMI/eDP Combo PHY driver" - depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF -diff --git a/drivers/phy/rockchip/Makefile b/drivers/phy/rockchip/Makefile -index 010a824..117aaff 100644 ---- a/drivers/phy/rockchip/Makefile -+++ b/drivers/phy/rockchip/Makefile -@@ -8,6 +8,7 @@ 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_SAMSUNG_DCPHY) += phy-rockchip-samsung-dcphy.o - obj-$(CONFIG_PHY_ROCKCHIP_SAMSUNG_HDPTX) += phy-rockchip-samsung-hdptx.o - obj-$(CONFIG_PHY_ROCKCHIP_SNPS_PCIE3) += phy-rockchip-snps-pcie3.o - obj-$(CONFIG_PHY_ROCKCHIP_TYPEC) += phy-rockchip-typec.o -diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c b/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c -new file mode 100644 -index 0000000..b897ecc ---- /dev/null -+++ b/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c -@@ -0,0 +1,1609 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Copyright (C) Rockchip Electronics Co.Ltd -+ * Author: -+ * Guochun Huang <hero.huang@rock-chips.com> -+ */ -+ -+#include <linux/clk.h> -+#include <linux/init.h> -+#include <linux/kernel.h> -+#include <linux/mfd/syscon.h> -+#include <linux/module.h> -+#include <linux/of_device.h> -+#include <linux/phy/phy.h> -+#include <linux/platform_device.h> -+#include <linux/pm_runtime.h> -+#include <linux/regmap.h> -+#include <linux/reset.h> -+ -+#define UPDATE(x, h, l) (((x) << (l)) & GENMASK((h), (l))) -+#define HIWORD_UPDATE(v, h, l) (((v) << (l)) | (GENMASK((h), (l)) << 16)) -+ -+#define BIAS_CON0 0x0000 -+#define BIAS_CON1 0x0004 -+#define BIAS_CON2 0x0008 -+#define BIAS_CON4 0x0010 -+#define I_MUX_SEL_MASK GENMASK(6, 5) -+#define I_MUX_SEL(x) UPDATE(x, 6, 5) -+#define I_MUX_SEL_400MV I_MUX_SEL(0) -+#define I_MUX_SEL_200MV I_MUX_SEL(1) -+#define I_MUX_SEL_530MV I_MUX_SEL(2) -+ -+#define PLL_CON0 0x0100 -+#define PLL_EN BIT(12) -+#define S_MASK GENMASK(10, 8) -+#define S(x) UPDATE(x, 10, 8) -+#define P_MASK GENMASK(5, 0) -+#define P(x) UPDATE(x, 5, 0) -+#define PLL_CON1 0x0104 -+#define PLL_CON2 0x0108 -+#define M_MASK GENMASK(9, 0) -+#define M(x) UPDATE(x, 9, 0) -+#define PLL_CON3 0x010c -+#define MRR_MASK GENMASK(13, 8) -+#define MRR(x) UPDATE(x, 13, 8) -+#define MFR_MASK GENMASK(7, 0) -+#define MFR(x) UPDATE(x, 7, 0) -+#define PLL_CON4 0x0110 -+#define SSCG_EN BIT(11) -+#define PLL_CON5 0x0114 -+#define RESET_N_SEL BIT(10) -+#define PLL_ENABLE_SEL BIT(8) -+#define PLL_CON6 0x0118 -+#define PLL_CON7 0x011c -+#define PLL_LOCK_CNT(x) UPDATE(x, 15, 0) -+#define PLL_CON8 0x0120 -+#define PLL_STB_CNT(x) UPDATE(x, 15, 0) -+#define PLL_STAT0 0x0140 -+#define PLL_LOCK BIT(0) -+ -+#define DPHY_MC_GNR_CON0 0x0300 -+#define PHY_READY BIT(1) -+#define PHY_ENABLE BIT(0) -+#define DPHY_MC_GNR_CON1 0x0304 -+#define T_PHY_READY(x) UPDATE(x, 15, 0) -+#define DPHY_MC_ANA_CON0 0x0308 -+#define DPHY_MC_ANA_CON1 0x030c -+#define DPHY_MC_ANA_CON2 0x0310 -+#define HS_VREG_AMP_ICON(x) UPDATE(x, 1, 0) -+#define DPHY_MC_TIME_CON0 0x0330 -+#define HSTX_CLK_SEL BIT(12) -+#define T_LPX(x) UPDATE(x, 11, 4) -+#define DPHY_MC_TIME_CON1 0x0334 -+#define T_CLK_ZERO(x) UPDATE(x, 15, 8) -+#define T_CLK_PREPARE(x) UPDATE(x, 7, 0) -+#define DPHY_MC_TIME_CON2 0x0338 -+#define T_HS_EXIT(x) UPDATE(x, 15, 8) -+#define T_CLK_TRAIL(x) UPDATE(x, 7, 0) -+#define DPHY_MC_TIME_CON3 0x033c -+#define T_CLK_POST(x) UPDATE(x, 7, 0) -+#define DPHY_MC_TIME_CON4 0x0340 -+#define T_ULPS_EXIT(x) UPDATE(x, 9, 0) -+#define DPHY_MC_DESKEW_CON0 0x0350 -+#define SKEW_CAL_RUN_TIME(x) UPDATE(x, 15, 12) -+ -+#define SKEW_CAL_INIT_RUN_TIME(x) UPDATE(x, 11, 8) -+#define SKEW_CAL_INIT_WAIT_TIME(x) UPDATE(x, 7, 4) -+#define SKEW_CAL_EN BIT(0) -+ -+#define COMBO_MD0_GNR_CON0 0x0400 -+#define COMBO_MD0_GNR_CON1 0x0404 -+#define COMBO_MD0_ANA_CON0 0x0408 -+#define COMBO_MD0_ANA_CON1 0x040C -+#define COMBO_MD0_ANA_CON2 0x0410 -+ -+#define COMBO_MD0_TIME_CON0 0x0430 -+#define COMBO_MD0_TIME_CON1 0x0434 -+#define COMBO_MD0_TIME_CON2 0x0438 -+#define COMBO_MD0_TIME_CON3 0x043C -+#define COMBO_MD0_TIME_CON4 0x0440 -+#define COMBO_MD0_DATA_CON0 0x0444 -+ -+#define COMBO_MD1_GNR_CON0 0x0500 -+#define COMBO_MD1_GNR_CON1 0x0504 -+#define COMBO_MD1_ANA_CON0 0x0508 -+#define COMBO_MD1_ANA_CON1 0x050c -+#define COMBO_MD1_ANA_CON2 0x0510 -+#define COMBO_MD1_TIME_CON0 0x0530 -+#define COMBO_MD1_TIME_CON1 0x0534 -+#define COMBO_MD1_TIME_CON2 0x0538 -+#define COMBO_MD1_TIME_CON3 0x053C -+#define COMBO_MD1_TIME_CON4 0x0540 -+#define COMBO_MD1_DATA_CON0 0x0544 -+ -+#define COMBO_MD2_GNR_CON0 0x0600 -+#define COMBO_MD2_GNR_CON1 0x0604 -+#define COMBO_MD2_ANA_CON0 0X0608 -+#define COMBO_MD2_ANA_CON1 0X060C -+#define COMBO_MD2_ANA_CON2 0X0610 -+#define COMBO_MD2_TIME_CON0 0x0630 -+#define COMBO_MD2_TIME_CON1 0x0634 -+#define COMBO_MD2_TIME_CON2 0x0638 -+#define COMBO_MD2_TIME_CON3 0x063C -+#define COMBO_MD2_TIME_CON4 0x0640 -+#define COMBO_MD2_DATA_CON0 0x0644 -+ -+#define DPHY_MD3_GNR_CON0 0x0700 -+#define DPHY_MD3_GNR_CON1 0x0704 -+#define DPHY_MD3_ANA_CON0 0X0708 -+#define DPHY_MD3_ANA_CON1 0X070C -+#define DPHY_MD3_ANA_CON2 0X0710 -+#define DPHY_MD3_TIME_CON0 0x0730 -+#define DPHY_MD3_TIME_CON1 0x0734 -+#define DPHY_MD3_TIME_CON2 0x0738 -+#define DPHY_MD3_TIME_CON3 0x073C -+#define DPHY_MD3_TIME_CON4 0x0740 -+#define DPHY_MD3_DATA_CON0 0x0744 -+ -+#define T_LP_EXIT_SKEW(x) UPDATE(x, 3, 2) -+#define T_LP_ENTRY_SKEW(x) UPDATE(x, 1, 0) -+#define T_HS_ZERO(x) UPDATE(x, 15, 8) -+#define T_HS_PREPARE(x) UPDATE(x, 7, 0) -+#define T_HS_EXIT(x) UPDATE(x, 15, 8) -+#define T_HS_TRAIL(x) UPDATE(x, 7, 0) -+#define T_TA_GET(x) UPDATE(x, 7, 4) -+#define T_TA_GO(x) UPDATE(x, 3, 0) -+ -+/* MIPICDPHY_GRF registers */ -+#define MIPICDPHY_GRF_CON0 0x0000 -+#define S_CPHY_MODE HIWORD_UPDATE(1, 3, 3) -+#define M_CPHY_MODE HIWORD_UPDATE(1, 0, 0) -+ -+#define MAX_DPHY_BW 4500000L -+#define MAX_CPHY_BW 2000000L -+ -+#define RX_CLK_THS_SETTLE (0xb30) -+#define RX_LANE0_THS_SETTLE (0xC30) -+#define RX_LANE0_ERR_SOT_SYNC (0xC34) -+#define RX_LANE1_THS_SETTLE (0xD30) -+#define RX_LANE1_ERR_SOT_SYNC (0xD34) -+#define RX_LANE2_THS_SETTLE (0xE30) -+#define RX_LANE2_ERR_SOT_SYNC (0xE34) -+#define RX_LANE3_THS_SETTLE (0xF30) -+#define RX_LANE3_ERR_SOT_SYNC (0xF34) -+#define RX_CLK_LANE_ENABLE (0xB00) -+#define RX_DATA_LANE0_ENABLE (0xC00) -+#define RX_DATA_LANE1_ENABLE (0xD00) -+#define RX_DATA_LANE2_ENABLE (0xE00) -+#define RX_DATA_LANE3_ENABLE (0xF00) -+ -+#define RX_S0C_GNR_CON1 (0xB04) -+#define RX_S0C_ANA_CON1 (0xB0c) -+#define RX_S0C_ANA_CON2 (0xB10) -+#define RX_S0C_ANA_CON3 (0xB14) -+#define RX_COMBO_S0D0_GNR_CON1 (0xC04) -+#define RX_COMBO_S0D0_ANA_CON1 (0xC0c) -+#define RX_COMBO_S0D0_ANA_CON2 (0xC10) -+#define RX_COMBO_S0D0_ANA_CON3 (0xC14) -+#define RX_COMBO_S0D0_ANA_CON6 (0xC20) -+#define RX_COMBO_S0D0_ANA_CON7 (0xC24) -+#define RX_COMBO_S0D0_DESKEW_CON0 (0xC40) -+#define RX_COMBO_S0D0_DESKEW_CON2 (0xC48) -+#define RX_COMBO_S0D0_DESKEW_CON4 (0xC50) -+#define RX_COMBO_S0D0_CRC_CON1 (0xC64) -+#define RX_COMBO_S0D0_CRC_CON2 (0xC68) -+#define RX_COMBO_S0D1_GNR_CON1 (0xD04) -+#define RX_COMBO_S0D1_ANA_CON1 (0xD0c) -+#define RX_COMBO_S0D1_ANA_CON2 (0xD10) -+#define RX_COMBO_S0D1_ANA_CON3 (0xD14) -+#define RX_COMBO_S0D1_ANA_CON6 (0xD20) -+#define RX_COMBO_S0D1_ANA_CON7 (0xD24) -+#define RX_COMBO_S0D1_DESKEW_CON0 (0xD40) -+#define RX_COMBO_S0D1_DESKEW_CON2 (0xD48) -+#define RX_COMBO_S0D1_DESKEW_CON4 (0xD50) -+#define RX_COMBO_S0D1_CRC_CON1 (0xD64) -+#define RX_COMBO_S0D1_CRC_CON2 (0xD68) -+#define RX_COMBO_S0D2_GNR_CON1 (0xE04) -+#define RX_COMBO_S0D2_ANA_CON1 (0xE0c) -+#define RX_COMBO_S0D2_ANA_CON2 (0xE10) -+#define RX_COMBO_S0D2_ANA_CON3 (0xE14) -+#define RX_COMBO_S0D2_ANA_CON6 (0xE20) -+#define RX_COMBO_S0D2_ANA_CON7 (0xE24) -+#define RX_COMBO_S0D2_DESKEW_CON0 (0xE40) -+#define RX_COMBO_S0D2_DESKEW_CON2 (0xE48) -+#define RX_COMBO_S0D2_DESKEW_CON4 (0xE50) -+#define RX_COMBO_S0D2_CRC_CON1 (0xE64) -+#define RX_COMBO_S0D2_CRC_CON2 (0xE68) -+#define RX_S0D3_GNR_CON1 (0xF04) -+#define RX_S0D3_ANA_CON1 (0xF0c) -+#define RX_S0D3_ANA_CON2 (0xF10) -+#define RX_S0D3_ANA_CON3 (0xF14) -+#define RX_S0D3_DESKEW_CON0 (0xF40) -+#define RX_S0D3_DESKEW_CON2 (0xF48) -+#define RX_S0D3_DESKEW_CON4 (0xF50) -+ -+struct samsung_mipi_dcphy { -+ struct device *dev; -+ struct clk *ref_clk; -+ struct clk *pclk; -+ struct regmap *regmap; -+ struct regmap *grf_regmap; -+ struct reset_control *m_phy_rst; -+ struct reset_control *s_phy_rst; -+ struct reset_control *apb_rst; -+ struct reset_control *grf_apb_rst; -+ unsigned int lanes; -+ -+ struct { -+ unsigned long long rate; -+ u8 prediv; -+ u16 fbdiv; -+ long dsm; -+ u8 scaler; -+ -+ bool ssc_en; -+ u8 mfr; -+ u8 mrr; -+ } pll; -+}; -+ -+struct samsung_mipi_dphy_timing { -+ unsigned int max_lane_mbps; -+ u8 clk_prepare; -+ u8 clk_zero; -+ u8 clk_post; -+ u8 clk_trail_eot; -+ u8 hs_prepare; -+ u8 hs_zero; -+ u8 hs_trail_eot; -+ u8 lpx; -+ u8 hs_exit; -+ u8 hs_settle; -+}; -+ -+static const -+struct samsung_mipi_dphy_timing samsung_mipi_dphy_timing_table[] = { -+ {6500, 32, 117, 31, 28, 30, 56, 27, 24, 44, 37}, -+ {6490, 32, 116, 31, 28, 30, 56, 27, 24, 44, 37}, -+ {6480, 32, 116, 31, 28, 30, 56, 27, 24, 44, 37}, -+ {6470, 32, 116, 31, 28, 30, 56, 27, 24, 44, 37}, -+ {6460, 32, 116, 31, 28, 30, 56, 27, 24, 44, 37}, -+ {6450, 32, 115, 31, 28, 30, 56, 27, 24, 44, 37}, -+ {6440, 32, 115, 31, 28, 30, 56, 27, 24, 44, 37}, -+ {6430, 31, 116, 31, 28, 30, 55, 27, 24, 44, 37}, -+ {6420, 31, 116, 31, 28, 30, 55, 27, 24, 44, 37}, -+ {6410, 31, 116, 31, 27, 30, 55, 27, 24, 44, 37}, -+ {6400, 31, 115, 30, 27, 30, 55, 27, 23, 43, 36}, -+ {6390, 31, 115, 30, 27, 30, 55, 27, 23, 43, 36}, -+ {6380, 31, 115, 30, 27, 30, 55, 27, 23, 43, 36}, -+ {6370, 31, 115, 30, 27, 30, 55, 26, 23, 43, 36}, -+ {6360, 31, 114, 30, 27, 30, 54, 26, 23, 43, 36}, -+ {6350, 31, 114, 30, 27, 30, 54, 26, 23, 43, 36}, -+ {6340, 31, 114, 30, 27, 30, 54, 26, 23, 43, 36}, -+ {6330, 31, 114, 30, 27, 30, 54, 26, 23, 43, 36}, -+ {6320, 31, 113, 30, 27, 30, 54, 26, 23, 43, 36}, -+ {6310, 31, 113, 30, 27, 30, 54, 26, 23, 43, 36}, -+ {6300, 31, 113, 30, 27, 30, 54, 26, 23, 43, 36}, -+ {6290, 31, 113, 30, 27, 29, 54, 26, 23, 43, 36}, -+ {6280, 31, 112, 30, 27, 29, 54, 26, 23, 43, 36}, -+ {6270, 31, 112, 30, 27, 29, 54, 26, 23, 43, 36}, -+ {6260, 31, 112, 30, 27, 29, 54, 26, 23, 43, 36}, -+ {6250, 31, 112, 30, 27, 29, 54, 26, 23, 42, 36}, -+ {6240, 30, 113, 30, 27, 29, 54, 26, 23, 42, 36}, -+ {6230, 30, 112, 30, 27, 29, 54, 26, 23, 42, 35}, -+ {6220, 30, 112, 30, 27, 29, 53, 26, 23, 42, 35}, -+ {6210, 30, 112, 30, 27, 29, 53, 26, 23, 42, 35}, -+ {6200, 30, 112, 29, 27, 29, 53, 26, 23, 42, 35}, -+ {6190, 30, 111, 29, 27, 29, 53, 26, 23, 42, 35}, -+ {6180, 30, 111, 29, 27, 29, 53, 26, 23, 42, 35}, -+ {6170, 30, 111, 29, 26, 29, 53, 26, 23, 42, 35}, -+ {6160, 30, 111, 29, 26, 29, 53, 26, 23, 42, 35}, -+ {6150, 30, 110, 29, 26, 29, 53, 26, 23, 42, 35}, -+ {6140, 30, 110, 29, 26, 29, 52, 26, 23, 42, 35}, -+ {6130, 30, 110, 29, 26, 29, 52, 25, 22, 42, 35}, -+ {6120, 30, 110, 29, 26, 29, 52, 25, 22, 42, 35}, -+ {6110, 30, 110, 29, 26, 29, 52, 25, 22, 42, 35}, -+ {6100, 30, 109, 29, 26, 29, 52, 25, 22, 41, 35}, -+ {6090, 30, 109, 29, 26, 29, 52, 25, 22, 41, 35}, -+ {6080, 30, 109, 29, 26, 28, 53, 25, 22, 41, 35}, -+ {6070, 30, 109, 29, 26, 28, 52, 25, 22, 41, 34}, -+ {6060, 30, 108, 29, 26, 28, 52, 25, 22, 41, 34}, -+ {6050, 30, 108, 29, 26, 28, 52, 25, 22, 41, 34}, -+ {6040, 29, 109, 29, 26, 28, 52, 25, 22, 41, 34}, -+ {6030, 29, 109, 29, 26, 28, 52, 25, 22, 41, 34}, -+ {6020, 29, 108, 29, 26, 28, 52, 25, 22, 41, 34}, -+ {6010, 29, 108, 29, 26, 28, 52, 25, 22, 41, 34}, -+ {6000, 29, 108, 28, 26, 28, 51, 25, 22, 41, 34}, -+ {5990, 29, 108, 28, 26, 28, 51, 25, 22, 41, 34}, -+ {5980, 29, 107, 28, 26, 28, 51, 25, 22, 41, 34}, -+ {5970, 29, 107, 28, 26, 28, 51, 25, 22, 41, 34}, -+ {5960, 29, 107, 28, 26, 28, 51, 25, 22, 40, 34}, -+ {5950, 29, 107, 28, 26, 28, 51, 25, 22, 40, 34}, -+ {5940, 29, 107, 28, 25, 28, 51, 25, 22, 40, 34}, -+ {5930, 29, 106, 28, 25, 28, 50, 25, 22, 40, 34}, -+ {5920, 29, 106, 28, 25, 28, 50, 25, 22, 40, 34}, -+ {5910, 29, 106, 28, 25, 28, 50, 25, 22, 40, 34}, -+ {5900, 29, 106, 28, 25, 28, 50, 24, 22, 40, 33}, -+ {5890, 29, 105, 28, 25, 28, 50, 24, 22, 40, 33}, -+ {5880, 29, 105, 28, 25, 28, 50, 24, 22, 40, 33}, -+ {5870, 29, 105, 28, 25, 27, 51, 24, 22, 40, 33}, -+ {5860, 29, 105, 28, 25, 27, 51, 24, 21, 40, 33}, -+ {5850, 29, 104, 28, 25, 27, 50, 24, 21, 40, 33}, -+ {5840, 28, 105, 28, 25, 27, 50, 24, 21, 40, 33}, -+ {5830, 28, 105, 28, 25, 27, 50, 24, 21, 40, 33}, -+ {5820, 28, 105, 28, 25, 27, 50, 24, 21, 40, 33}, -+ {5810, 28, 104, 28, 25, 27, 50, 24, 21, 39, 33}, -+ {5800, 28, 104, 27, 25, 27, 50, 24, 21, 39, 33}, -+ {5790, 28, 104, 27, 25, 27, 50, 24, 21, 39, 33}, -+ {5780, 28, 104, 27, 25, 27, 49, 24, 21, 39, 33}, -+ {5770, 28, 104, 27, 25, 27, 49, 24, 21, 39, 33}, -+ {5760, 28, 103, 27, 25, 27, 49, 24, 21, 39, 33}, -+ {5750, 28, 103, 27, 25, 27, 49, 24, 21, 39, 33}, -+ {5740, 28, 103, 27, 25, 27, 49, 24, 21, 39, 33}, -+ {5730, 28, 103, 27, 25, 27, 49, 24, 21, 39, 32}, -+ {5720, 28, 102, 27, 25, 27, 49, 24, 21, 39, 32}, -+ {5710, 28, 102, 27, 25, 27, 48, 24, 21, 39, 32}, -+ {5700, 28, 102, 27, 24, 27, 48, 24, 21, 39, 32}, -+ {5690, 28, 102, 27, 24, 27, 48, 24, 21, 39, 32}, -+ {5680, 28, 101, 27, 24, 27, 48, 24, 21, 39, 32}, -+ {5670, 28, 101, 27, 24, 27, 48, 23, 21, 38, 32}, -+ {5660, 28, 101, 27, 24, 26, 49, 23, 21, 38, 32}, -+ {5650, 28, 101, 27, 24, 26, 49, 23, 21, 38, 32}, -+ {5640, 27, 101, 27, 24, 26, 48, 23, 21, 38, 32}, -+ {5630, 27, 101, 27, 24, 26, 48, 23, 21, 38, 32}, -+ {5620, 27, 101, 27, 24, 26, 48, 23, 21, 38, 32}, -+ {5610, 27, 101, 27, 24, 26, 48, 23, 21, 38, 32}, -+ {5600, 27, 101, 26, 24, 26, 48, 23, 20, 38, 32}, -+ {5590, 27, 100, 26, 24, 26, 48, 23, 20, 38, 32}, -+ {5580, 27, 100, 26, 24, 26, 48, 23, 20, 38, 32}, -+ {5570, 27, 100, 26, 24, 26, 48, 23, 20, 38, 31}, -+ {5560, 27, 100, 26, 24, 26, 47, 23, 20, 38, 31}, -+ {5550, 27, 99, 26, 24, 26, 47, 23, 20, 38, 31}, -+ {5540, 27, 99, 26, 24, 26, 47, 23, 20, 38, 31}, -+ {5530, 27, 99, 26, 24, 26, 47, 23, 20, 38, 31}, -+ {5520, 27, 99, 26, 24, 26, 47, 23, 20, 37, 31}, -+ {5510, 27, 98, 26, 24, 26, 47, 23, 20, 37, 31}, -+ {5500, 27, 98, 26, 24, 26, 47, 23, 20, 37, 31}, -+ {5490, 27, 98, 26, 24, 26, 46, 23, 20, 37, 31}, -+ {5480, 27, 98, 26, 24, 26, 46, 23, 20, 37, 31}, -+ {5470, 27, 97, 26, 23, 26, 46, 23, 20, 37, 31}, -+ {5460, 27, 97, 26, 23, 26, 46, 23, 20, 37, 31}, -+ {5450, 27, 97, 26, 23, 25, 47, 23, 20, 37, 31}, -+ {5440, 26, 98, 26, 23, 25, 47, 23, 20, 37, 31}, -+ {5430, 26, 98, 26, 23, 25, 47, 22, 20, 37, 31}, -+ {5420, 26, 97, 26, 23, 25, 46, 22, 20, 37, 31}, -+ {5410, 26, 97, 26, 23, 25, 46, 22, 20, 37, 31}, -+ {5400, 26, 97, 25, 23, 25, 46, 22, 20, 37, 30}, -+ {5390, 26, 97, 25, 23, 25, 46, 22, 20, 37, 30}, -+ {5380, 26, 96, 25, 23, 25, 46, 22, 20, 36, 30}, -+ {5370, 26, 96, 25, 23, 25, 46, 22, 20, 36, 30}, -+ {5360, 26, 96, 25, 23, 25, 46, 22, 20, 36, 30}, -+ {5350, 26, 96, 25, 23, 25, 46, 22, 20, 36, 30}, -+ {5340, 26, 95, 25, 23, 25, 45, 22, 20, 36, 30}, -+ {5330, 26, 95, 25, 23, 25, 45, 22, 19, 36, 30}, -+ {5320, 26, 95, 25, 23, 25, 45, 22, 19, 36, 30}, -+ {5310, 26, 95, 25, 23, 25, 45, 22, 19, 36, 30}, -+ {5300, 26, 95, 25, 23, 25, 45, 22, 19, 36, 30}, -+ {5290, 26, 94, 25, 23, 25, 45, 22, 19, 36, 30}, -+ {5280, 26, 94, 25, 23, 25, 45, 22, 19, 36, 30}, -+ {5270, 26, 94, 25, 23, 25, 44, 22, 19, 36, 30}, -+ {5260, 26, 94, 25, 23, 25, 44, 22, 19, 36, 30}, -+ {5250, 25, 94, 25, 23, 24, 45, 22, 19, 36, 30}, -+ {5240, 25, 94, 25, 23, 24, 45, 22, 19, 36, 29}, -+ {5230, 25, 94, 25, 22, 24, 45, 22, 19, 35, 29}, -+ {5220, 25, 94, 25, 22, 24, 45, 22, 19, 35, 29}, -+ {5210, 25, 93, 25, 22, 24, 45, 22, 19, 35, 29}, -+ {5200, 25, 93, 24, 22, 24, 44, 21, 19, 35, 29}, -+ {5190, 25, 93, 24, 22, 24, 44, 21, 19, 35, 29}, -+ {5180, 25, 93, 24, 22, 24, 44, 21, 19, 35, 29}, -+ {5170, 25, 92, 24, 22, 24, 44, 21, 19, 35, 29}, -+ {5160, 25, 92, 24, 22, 24, 44, 21, 19, 35, 29}, -+ {5150, 25, 92, 24, 22, 24, 44, 21, 19, 35, 29}, -+ {5140, 25, 92, 24, 22, 24, 44, 21, 19, 35, 29}, -+ {5130, 25, 92, 24, 22, 24, 43, 21, 19, 35, 29}, -+ {5120, 25, 91, 24, 22, 24, 43, 21, 19, 35, 29}, -+ {5110, 25, 91, 24, 22, 24, 43, 21, 19, 35, 29}, -+ {5100, 25, 91, 24, 22, 24, 43, 21, 19, 35, 29}, -+ {5090, 25, 91, 24, 22, 24, 43, 21, 19, 34, 29}, -+ {5080, 25, 90, 24, 22, 24, 43, 21, 19, 34, 29}, -+ {5070, 25, 90, 24, 22, 24, 43, 21, 19, 34, 28}, -+ {5060, 25, 90, 24, 22, 24, 43, 21, 18, 34, 28}, -+ {5050, 24, 91, 24, 22, 24, 42, 21, 18, 34, 28}, -+ {5040, 24, 90, 24, 22, 23, 43, 21, 18, 34, 28}, -+ {5030, 24, 90, 24, 22, 23, 43, 21, 18, 34, 28}, -+ {5020, 24, 90, 24, 22, 23, 43, 21, 18, 34, 28}, -+ {5010, 24, 90, 24, 22, 23, 43, 21, 18, 34, 28}, -+ {5000, 24, 89, 23, 21, 23, 43, 21, 18, 34, 28}, -+ {4990, 24, 89, 23, 21, 23, 43, 21, 18, 34, 28}, -+ {4980, 24, 89, 23, 21, 23, 42, 21, 18, 34, 28}, -+ {4970, 24, 89, 23, 21, 23, 42, 21, 18, 34, 28}, -+ {4960, 24, 89, 23, 21, 23, 42, 20, 18, 34, 28}, -+ {4950, 24, 88, 23, 21, 23, 42, 20, 18, 34, 28}, -+ {4940, 24, 88, 23, 21, 23, 42, 20, 18, 33, 28}, -+ {4930, 24, 88, 23, 21, 23, 42, 20, 18, 33, 28}, -+ {4920, 24, 88, 23, 21, 23, 42, 20, 18, 33, 28}, -+ {4910, 24, 87, 23, 21, 23, 41, 20, 18, 33, 28}, -+ {4900, 24, 87, 23, 21, 23, 41, 20, 18, 33, 27}, -+ {4890, 24, 87, 23, 21, 23, 41, 20, 18, 33, 27}, -+ {4880, 24, 87, 23, 21, 23, 41, 20, 18, 33, 27}, -+ {4870, 24, 86, 23, 21, 23, 41, 20, 18, 33, 27}, -+ {4860, 24, 86, 23, 21, 23, 41, 20, 18, 33, 27}, -+ {4850, 23, 87, 23, 21, 23, 41, 20, 18, 33, 27}, -+ {4840, 23, 87, 23, 21, 23, 40, 20, 18, 33, 27}, -+ {4830, 23, 86, 23, 21, 22, 41, 20, 18, 33, 27}, -+ {4820, 23, 86, 23, 21, 22, 41, 20, 18, 33, 27}, -+ {4810, 23, 86, 23, 21, 22, 41, 20, 18, 33, 27}, -+ {4800, 23, 86, 22, 21, 22, 41, 20, 17, 32, 27}, -+ {4790, 23, 86, 22, 21, 22, 41, 20, 17, 32, 27}, -+ {4780, 23, 85, 22, 21, 22, 41, 20, 17, 32, 27}, -+ {4770, 23, 85, 22, 21, 22, 41, 20, 17, 32, 27}, -+ {4760, 23, 85, 22, 20, 22, 40, 20, 17, 32, 27}, -+ {4750, 23, 85, 22, 20, 22, 40, 20, 17, 32, 27}, -+ {4740, 23, 84, 22, 20, 22, 40, 20, 17, 32, 26}, -+ {4730, 23, 84, 22, 20, 22, 40, 19, 17, 32, 26}, -+ {4720, 23, 84, 22, 20, 22, 40, 19, 17, 32, 26}, -+ {4710, 23, 84, 22, 20, 22, 40, 19, 17, 32, 26}, -+ {4700, 23, 83, 22, 20, 22, 40, 19, 17, 32, 26}, -+ {4690, 23, 83, 22, 20, 22, 39, 19, 17, 32, 26}, -+ {4680, 23, 83, 22, 20, 22, 39, 19, 17, 32, 26}, -+ {4670, 23, 83, 22, 20, 22, 39, 19, 17, 32, 26}, -+ {4660, 23, 82, 22, 20, 22, 39, 19, 17, 32, 26}, -+ {4650, 22, 83, 22, 20, 22, 39, 19, 17, 31, 26}, -+ {4640, 22, 83, 22, 20, 22, 39, 19, 17, 31, 26}, -+ {4630, 22, 83, 22, 20, 22, 39, 19, 17, 31, 26}, -+ {4620, 22, 83, 22, 20, 21, 39, 19, 17, 31, 26}, -+ {4610, 22, 82, 22, 20, 21, 39, 19, 17, 31, 26}, -+ {4600, 22, 82, 21, 20, 21, 39, 19, 17, 31, 26}, -+ {4590, 22, 82, 21, 20, 21, 39, 19, 17, 31, 26}, -+ {4580, 22, 82, 21, 20, 21, 39, 19, 17, 31, 26}, -+ {4570, 22, 81, 21, 20, 21, 39, 19, 17, 31, 25}, -+ {4560, 22, 81, 21, 20, 21, 39, 19, 17, 31, 25}, -+ {4550, 22, 81, 21, 20, 21, 38, 19, 17, 31, 25}, -+ {4540, 22, 81, 21, 20, 21, 38, 19, 17, 31, 25}, -+ {4530, 22, 80, 21, 19, 21, 38, 19, 16, 31, 25}, -+ {4520, 22, 80, 21, 19, 21, 38, 19, 16, 31, 25}, -+ {4510, 22, 80, 21, 19, 21, 38, 19, 16, 31, 25}, -+ {4500, 22, 80, 21, 19, 21, 38, 19, 16, 30, 25}, -+ {4490, 22, 80, 21, 19, 21, 38, 18, 16, 30, 25}, -+ {4480, 22, 79, 21, 19, 21, 38, 18, 16, 30, 25}, -+ {4470, 22, 79, 21, 19, 21, 37, 18, 16, 30, 25}, -+ {4460, 22, 79, 21, 19, 21, 37, 18, 16, 30, 25}, -+ {4450, 21, 80, 21, 19, 21, 37, 18, 16, 30, 25}, -+ {4440, 21, 79, 21, 19, 21, 37, 18, 16, 30, 25}, -+ {4430, 21, 79, 21, 19, 21, 37, 18, 16, 30, 25}, -+ {4420, 21, 79, 21, 19, 21, 37, 18, 16, 30, 25}, -+ {4410, 21, 79, 21, 19, 20, 38, 18, 16, 30, 25}, -+ {4400, 21, 78, 20, 19, 20, 37, 18, 16, 30, 24}, -+ {4390, 21, 78, 20, 19, 20, 37, 18, 16, 30, 24}, -+ {4380, 21, 78, 20, 19, 20, 37, 18, 16, 30, 24}, -+ {4370, 21, 78, 20, 19, 20, 37, 18, 16, 30, 24}, -+ {4360, 21, 77, 20, 19, 20, 37, 18, 16, 29, 24}, -+ {4350, 21, 77, 20, 19, 20, 37, 18, 16, 29, 24}, -+ {4340, 21, 77, 20, 19, 20, 37, 18, 16, 29, 24}, -+ {4330, 21, 77, 20, 19, 20, 36, 18, 16, 29, 24}, -+ {4320, 21, 77, 20, 19, 20, 36, 18, 16, 29, 24}, -+ {4310, 21, 76, 20, 19, 20, 36, 18, 16, 29, 24}, -+ {4300, 21, 76, 20, 18, 20, 36, 18, 16, 29, 24}, -+ {4290, 21, 76, 20, 18, 20, 36, 18, 16, 29, 24}, -+ {4280, 21, 76, 20, 18, 20, 36, 18, 16, 29, 24}, -+ {4270, 21, 75, 20, 18, 20, 36, 18, 16, 29, 24}, -+ {4260, 21, 75, 20, 18, 20, 35, 17, 15, 29, 24}, -+ {4250, 20, 76, 20, 18, 20, 35, 17, 15, 29, 24}, -+ {4240, 20, 76, 20, 18, 20, 35, 17, 15, 29, 23}, -+ {4230, 20, 75, 20, 18, 20, 35, 17, 15, 29, 23}, -+ {4220, 20, 75, 20, 18, 20, 35, 17, 15, 29, 23}, -+ {4210, 20, 75, 20, 18, 20, 35, 17, 15, 28, 23}, -+ {4200, 20, 75, 19, 18, 19, 36, 17, 15, 28, 23}, -+ {4190, 20, 74, 19, 18, 19, 36, 17, 15, 28, 23}, -+ {4180, 20, 74, 19, 18, 19, 35, 17, 15, 28, 23}, -+ {4170, 20, 74, 19, 18, 19, 35, 17, 15, 28, 23}, -+ {4160, 20, 74, 19, 18, 19, 35, 17, 15, 28, 23}, -+ {4150, 20, 74, 19, 18, 19, 35, 17, 15, 28, 23}, -+ {4140, 20, 73, 19, 18, 19, 35, 17, 15, 28, 23}, -+ {4130, 20, 73, 19, 18, 19, 35, 17, 15, 28, 23}, -+ {4120, 20, 73, 19, 18, 19, 35, 17, 15, 28, 23}, -+ {4110, 20, 73, 19, 18, 19, 34, 17, 15, 28, 23}, -+ {4100, 20, 72, 19, 18, 19, 34, 17, 15, 28, 23}, -+ {4090, 20, 72, 19, 18, 19, 34, 17, 15, 28, 23}, -+ {4080, 20, 72, 19, 18, 19, 34, 17, 15, 28, 23}, -+ {4070, 20, 72, 19, 18, 19, 34, 17, 15, 27, 22}, -+ {4060, 19, 72, 19, 17, 19, 34, 17, 15, 27, 22}, -+ {4050, 19, 72, 19, 17, 19, 34, 17, 15, 27, 22}, -+ {4040, 19, 72, 19, 17, 19, 33, 17, 15, 27, 22}, -+ {4030, 19, 72, 19, 17, 19, 33, 17, 15, 27, 22}, -+ {4020, 19, 71, 19, 17, 19, 33, 16, 15, 27, 22}, -+ {4010, 19, 71, 19, 17, 19, 33, 16, 15, 27, 22}, -+ {4000, 19, 71, 18, 17, 19, 33, 16, 14, 27, 22}, -+ {3990, 19, 71, 18, 17, 18, 34, 16, 14, 27, 22}, -+ {3980, 19, 71, 18, 17, 18, 34, 16, 14, 27, 22}, -+ {3970, 19, 70, 18, 17, 18, 33, 16, 14, 27, 22}, -+ {3960, 19, 70, 18, 17, 18, 33, 16, 14, 27, 22}, -+ {3950, 19, 70, 18, 17, 18, 33, 16, 14, 27, 22}, -+ {3940, 19, 70, 18, 17, 18, 33, 16, 14, 27, 22}, -+ {3930, 19, 69, 18, 17, 18, 33, 16, 14, 27, 22}, -+ {3920, 19, 69, 18, 17, 18, 33, 16, 14, 26, 22}, -+ {3910, 19, 69, 18, 17, 18, 33, 16, 14, 26, 22}, -+ {3900, 19, 69, 18, 17, 18, 33, 16, 14, 26, 21}, -+ {3890, 19, 68, 18, 17, 18, 32, 16, 14, 26, 21}, -+ {3880, 19, 68, 18, 17, 18, 32, 16, 14, 26, 21}, -+ {3870, 19, 68, 18, 17, 18, 32, 16, 14, 26, 21}, -+ {3860, 18, 69, 18, 17, 18, 32, 16, 14, 26, 21}, -+ {3850, 18, 68, 18, 17, 18, 32, 16, 14, 26, 21}, -+ {3840, 18, 68, 18, 17, 18, 32, 16, 14, 26, 21}, -+ {3830, 18, 68, 18, 16, 18, 32, 16, 14, 26, 21}, -+ {3820, 18, 68, 18, 16, 18, 31, 16, 14, 26, 21}, -+ {3810, 18, 68, 18, 16, 18, 31, 16, 14, 26, 21}, -+ {3800, 18, 67, 17, 16, 18, 31, 16, 14, 26, 21}, -+ {3790, 18, 67, 17, 16, 17, 32, 15, 14, 26, 21}, -+ {3780, 18, 67, 17, 16, 17, 32, 15, 14, 25, 21}, -+ {3770, 18, 67, 17, 16, 17, 32, 15, 14, 25, 21}, -+ {3760, 18, 66, 17, 16, 17, 32, 15, 14, 25, 21}, -+ {3750, 18, 66, 17, 16, 17, 31, 15, 14, 25, 21}, -+ {3740, 18, 66, 17, 16, 17, 31, 15, 14, 25, 20}, -+ {3730, 18, 66, 17, 16, 17, 31, 15, 13, 25, 20}, -+ {3720, 18, 65, 17, 16, 17, 31, 15, 13, 25, 20}, -+ {3710, 18, 65, 17, 16, 17, 31, 15, 13, 25, 20}, -+ {3700, 18, 65, 17, 16, 17, 31, 15, 13, 25, 20}, -+ {3690, 18, 65, 17, 16, 17, 31, 15, 13, 25, 20}, -+ {3680, 18, 64, 17, 16, 17, 31, 15, 13, 25, 20}, -+ {3670, 18, 64, 17, 16, 17, 30, 15, 13, 25, 20}, -+ {3660, 17, 65, 17, 16, 17, 30, 15, 13, 25, 20}, -+ {3650, 17, 65, 17, 16, 17, 30, 15, 13, 25, 20}, -+ {3640, 17, 65, 17, 16, 17, 30, 15, 13, 25, 20}, -+ {3630, 17, 64, 17, 16, 17, 30, 15, 13, 24, 20}, -+ {3620, 17, 64, 17, 16, 17, 30, 15, 13, 24, 20}, -+ {3610, 17, 64, 17, 16, 17, 30, 15, 13, 24, 20}, -+ {3600, 17, 64, 16, 16, 17, 29, 15, 13, 24, 20}, -+ {3590, 17, 63, 16, 15, 17, 29, 15, 13, 24, 20}, -+ {3580, 17, 63, 16, 15, 16, 30, 15, 13, 24, 20}, -+ {3570, 17, 63, 16, 15, 16, 30, 15, 13, 24, 19}, -+ {3560, 17, 63, 16, 15, 16, 30, 14, 13, 24, 19}, -+ {3550, 17, 62, 16, 15, 16, 30, 14, 13, 24, 19}, -+ {3540, 17, 62, 16, 15, 16, 30, 14, 13, 24, 19}, -+ {3530, 17, 62, 16, 15, 16, 29, 14, 13, 24, 19}, -+ {3520, 17, 62, 16, 15, 16, 29, 14, 13, 24, 19}, -+ {3510, 17, 62, 16, 15, 16, 29, 14, 13, 24, 19}, -+ {3500, 17, 61, 16, 15, 16, 29, 14, 13, 24, 19}, -+ {3490, 17, 61, 16, 15, 16, 29, 14, 13, 23, 19}, -+ {3480, 17, 61, 16, 15, 16, 29, 14, 13, 23, 19}, -+ {3470, 17, 61, 16, 15, 16, 29, 14, 13, 23, 19}, -+ {3460, 16, 61, 16, 15, 16, 28, 14, 12, 23, 19}, -+ {3450, 16, 61, 16, 15, 16, 28, 14, 12, 23, 19}, -+ {3440, 16, 61, 16, 15, 16, 28, 14, 12, 23, 19}, -+ {3430, 16, 61, 16, 15, 16, 28, 14, 12, 23, 19}, -+ {3420, 16, 60, 16, 15, 16, 28, 14, 12, 23, 19}, -+ {3410, 16, 60, 16, 15, 16, 28, 14, 12, 23, 18}, -+ {3400, 16, 60, 15, 15, 16, 28, 14, 12, 23, 18}, -+ {3390, 16, 60, 15, 15, 16, 28, 14, 12, 23, 18}, -+ {3380, 16, 59, 15, 15, 16, 27, 14, 12, 23, 18}, -+ {3370, 16, 59, 15, 15, 15, 28, 14, 12, 23, 18}, -+ {3360, 16, 59, 15, 14, 15, 28, 14, 12, 23, 18}, -+ {3350, 16, 59, 15, 14, 15, 28, 14, 12, 23, 18}, -+ {3340, 16, 59, 15, 14, 15, 28, 14, 12, 22, 18}, -+ {3330, 16, 58, 15, 14, 15, 28, 14, 12, 22, 18}, -+ {3320, 16, 58, 15, 14, 15, 28, 13, 12, 22, 18}, -+ {3310, 16, 58, 15, 14, 15, 27, 13, 12, 22, 18}, -+ {3300, 16, 58, 15, 14, 15, 27, 13, 12, 22, 18}, -+ {3290, 16, 57, 15, 14, 15, 27, 13, 12, 22, 18}, -+ {3280, 16, 57, 15, 14, 15, 27, 13, 12, 22, 18}, -+ {3270, 16, 57, 15, 14, 15, 27, 13, 12, 22, 18}, -+ {3260, 15, 58, 15, 14, 15, 27, 13, 12, 22, 18}, -+ {3250, 15, 57, 15, 14, 15, 27, 13, 12, 22, 18}, -+ {3240, 15, 57, 15, 14, 15, 26, 13, 12, 22, 17}, -+ {3230, 15, 57, 15, 14, 15, 26, 13, 12, 22, 17}, -+ {3220, 15, 57, 15, 14, 15, 26, 13, 12, 22, 17}, -+ {3210, 15, 56, 15, 14, 15, 26, 13, 12, 22, 17}, -+ {3200, 15, 56, 14, 14, 15, 26, 13, 11, 21, 17}, -+ {3190, 15, 56, 14, 14, 15, 26, 13, 11, 21, 17}, -+ {3180, 15, 56, 14, 14, 15, 26, 13, 11, 21, 17}, -+ {3170, 15, 56, 14, 14, 15, 25, 13, 11, 21, 17}, -+ {3160, 15, 55, 14, 14, 14, 26, 13, 11, 21, 17}, -+ {3150, 15, 55, 14, 14, 14, 26, 13, 11, 21, 17}, -+ {3140, 15, 55, 14, 14, 14, 26, 13, 11, 21, 17}, -+ {3130, 15, 55, 14, 14, 14, 26, 13, 11, 21, 17}, -+ {3120, 15, 54, 14, 13, 14, 26, 13, 11, 21, 17}, -+ {3110, 15, 54, 14, 13, 14, 26, 13, 11, 21, 17}, -+ {3100, 15, 54, 14, 13, 14, 26, 13, 11, 21, 17}, -+ {3090, 15, 54, 14, 13, 14, 25, 12, 11, 21, 17}, -+ {3080, 15, 53, 14, 13, 14, 25, 12, 11, 21, 17}, -+ {3070, 14, 54, 14, 13, 14, 25, 12, 11, 21, 16}, -+ {3060, 14, 54, 14, 13, 14, 25, 12, 11, 21, 16}, -+ {3050, 14, 54, 14, 13, 14, 25, 12, 11, 20, 16}, -+ {3040, 14, 53, 14, 13, 14, 25, 12, 11, 20, 16}, -+ {3030, 14, 53, 14, 13, 14, 25, 12, 11, 20, 16}, -+ {3020, 14, 53, 14, 13, 14, 24, 12, 11, 20, 16}, -+ {3010, 14, 53, 14, 13, 14, 24, 12, 11, 20, 16}, -+ {3000, 14, 53, 13, 13, 14, 24, 12, 11, 20, 16}, -+ {2990, 14, 52, 13, 13, 14, 24, 12, 11, 20, 16}, -+ {2980, 14, 52, 13, 13, 14, 24, 12, 11, 20, 16}, -+ {2970, 14, 52, 13, 13, 14, 24, 12, 11, 20, 16}, -+ {2960, 14, 52, 13, 13, 14, 24, 12, 11, 20, 16}, -+ {2950, 14, 51, 13, 13, 13, 24, 12, 11, 20, 16}, -+ {2940, 14, 51, 13, 13, 13, 24, 12, 11, 20, 16}, -+ {2930, 14, 51, 13, 13, 13, 24, 12, 10, 20, 16}, -+ {2920, 14, 51, 13, 13, 13, 24, 12, 10, 20, 16}, -+ {2910, 14, 50, 13, 13, 13, 24, 12, 10, 20, 15}, -+ {2900, 14, 50, 13, 13, 13, 24, 12, 10, 19, 15}, -+ {2890, 14, 50, 13, 12, 13, 24, 12, 10, 19, 15}, -+ {2880, 14, 50, 13, 12, 13, 23, 12, 10, 19, 15}, -+ {2870, 13, 50, 13, 12, 13, 23, 12, 10, 19, 15}, -+ {2860, 13, 50, 13, 12, 13, 23, 12, 10, 19, 15}, -+ {2850, 13, 50, 13, 12, 13, 23, 11, 10, 19, 15}, -+ {2840, 13, 50, 13, 12, 13, 23, 11, 10, 19, 15}, -+ {2830, 13, 50, 13, 12, 13, 23, 11, 10, 19, 15}, -+ {2820, 13, 49, 13, 12, 13, 23, 11, 10, 19, 15}, -+ {2810, 13, 49, 13, 12, 13, 23, 11, 10, 19, 15}, -+ {2800, 13, 49, 12, 12, 13, 22, 11, 10, 19, 15}, -+ {2790, 13, 49, 12, 12, 13, 22, 11, 10, 19, 15}, -+ {2780, 13, 48, 12, 12, 13, 22, 11, 10, 19, 15}, -+ {2770, 13, 48, 12, 12, 13, 22, 11, 10, 19, 15}, -+ {2760, 13, 48, 12, 12, 13, 22, 11, 10, 18, 15}, -+ {2750, 13, 48, 12, 12, 13, 22, 11, 10, 18, 15}, -+ {2740, 13, 47, 12, 12, 12, 23, 11, 10, 18, 14}, -+ {2730, 13, 47, 12, 12, 12, 22, 11, 10, 18, 14}, -+ {2720, 13, 47, 12, 12, 12, 22, 11, 10, 18, 14}, -+ {2710, 13, 47, 12, 12, 12, 22, 11, 10, 18, 14}, -+ {2700, 13, 47, 12, 12, 12, 22, 11, 10, 18, 14}, -+ {2690, 13, 46, 12, 12, 12, 22, 11, 10, 18, 14}, -+ {2680, 13, 46, 12, 12, 12, 22, 11, 10, 18, 14}, -+ {2670, 12, 47, 12, 12, 12, 22, 11, 10, 18, 14}, -+ {2660, 12, 47, 12, 12, 12, 21, 11, 9, 18, 14}, -+ {2650, 12, 46, 12, 11, 12, 21, 11, 9, 18, 14}, -+ {2640, 12, 46, 12, 11, 12, 21, 11, 9, 18, 14}, -+ {2630, 12, 46, 12, 11, 12, 21, 11, 9, 18, 14}, -+ {2620, 12, 46, 12, 11, 12, 21, 10, 9, 18, 14}, -+ {2610, 12, 45, 12, 11, 12, 21, 10, 9, 17, 14}, -+ {2600, 12, 45, 11, 11, 12, 21, 10, 9, 17, 14}, -+ {2590, 12, 45, 11, 11, 12, 20, 10, 9, 17, 14}, -+ {2580, 12, 45, 11, 11, 12, 20, 10, 9, 17, 14}, -+ {2570, 12, 44, 11, 11, 12, 20, 10, 9, 17, 13}, -+ {2560, 12, 44, 11, 11, 12, 20, 10, 9, 17, 13}, -+ {2550, 12, 44, 11, 11, 12, 20, 10, 9, 17, 13}, -+ {2540, 12, 44, 11, 11, 11, 21, 10, 9, 17, 13}, -+ {2530, 12, 44, 11, 11, 11, 21, 10, 9, 17, 13}, -+ {2520, 12, 43, 11, 11, 11, 21, 10, 9, 17, 13}, -+ {2510, 12, 43, 11, 11, 11, 20, 10, 9, 17, 13}, -+ {2500, 12, 43, 11, 11, 11, 20, 10, 9, 17, 13}, -+ {2490, 12, 43, 11, 11, 11, 20, 10, 9, 17, 13}, -+ {2480, 12, 42, 11, 11, 11, 20, 10, 9, 17, 13}, -+ {2470, 11, 43, 11, 11, 11, 20, 10, 9, 16, 13}, -+ {2460, 11, 43, 11, 11, 11, 20, 10, 9, 16, 13}, -+ {2450, 11, 43, 11, 11, 11, 20, 10, 9, 16, 13}, -+ {2440, 11, 42, 11, 11, 11, 19, 10, 9, 16, 13}, -+ {2430, 11, 42, 11, 11, 11, 19, 10, 9, 16, 13}, -+ {2420, 11, 42, 11, 10, 11, 19, 10, 9, 16, 13}, -+ {2410, 11, 42, 11, 10, 11, 19, 10, 9, 16, 12}, -+ {2400, 11, 41, 10, 10, 11, 19, 10, 8, 16, 12}, -+ {2390, 11, 41, 10, 10, 11, 19, 10, 8, 16, 12}, -+ {2380, 11, 41, 10, 10, 11, 19, 9, 8, 16, 12}, -+ {2370, 11, 41, 10, 10, 11, 18, 9, 8, 16, 12}, -+ {2360, 11, 41, 10, 10, 11, 18, 9, 8, 16, 12}, -+ {2350, 11, 40, 10, 10, 11, 18, 9, 8, 16, 12}, -+ {2340, 11, 40, 10, 10, 11, 18, 9, 8, 16, 12}, -+ {2330, 11, 40, 10, 10, 10, 19, 9, 8, 16, 12}, -+ {2320, 11, 40, 10, 10, 10, 19, 9, 8, 15, 12}, -+ {2310, 11, 39, 10, 10, 10, 19, 9, 8, 15, 12}, -+ {2300, 11, 39, 10, 10, 10, 18, 9, 8, 15, 12}, -+ {2290, 11, 39, 10, 10, 10, 18, 9, 8, 15, 12}, -+ {2280, 11, 39, 10, 10, 10, 18, 9, 8, 15, 12}, -+ {2270, 10, 39, 10, 10, 10, 18, 9, 8, 15, 12}, -+ {2260, 10, 39, 10, 10, 10, 18, 9, 8, 15, 12}, -+ {2250, 10, 39, 10, 10, 10, 18, 9, 8, 15, 12}, -+ {2240, 10, 39, 10, 10, 10, 18, 9, 8, 15, 11}, -+ {2230, 10, 38, 10, 10, 10, 18, 9, 8, 15, 11}, -+ {2220, 10, 38, 10, 10, 10, 17, 9, 8, 15, 11}, -+ {2210, 10, 38, 10, 10, 10, 17, 9, 8, 15, 11}, -+ {2200, 10, 38, 9, 10, 10, 17, 9, 8, 15, 11}, -+ {2190, 10, 38, 9, 9, 10, 17, 9, 8, 15, 11}, -+ {2180, 10, 37, 9, 9, 10, 17, 9, 8, 14, 11}, -+ {2170, 10, 37, 9, 9, 10, 17, 9, 8, 14, 11}, -+ {2160, 10, 37, 9, 9, 10, 17, 9, 8, 14, 11}, -+ {2150, 10, 37, 9, 9, 10, 16, 8, 8, 14, 11}, -+ {2140, 10, 36, 9, 9, 10, 16, 8, 8, 14, 11}, -+ {2130, 10, 36, 9, 9, 10, 16, 8, 7, 14, 11}, -+ {2120, 10, 36, 9, 9, 9, 17, 8, 7, 14, 11}, -+ {2110, 10, 36, 9, 9, 9, 17, 8, 7, 14, 11}, -+ {2100, 10, 35, 9, 9, 9, 17, 8, 7, 14, 11}, -+ {2090, 10, 35, 9, 9, 9, 17, 8, 7, 14, 11}, -+ {2080, 9, 36, 9, 9, 9, 16, 8, 7, 14, 11}, -+ {2070, 9, 36, 9, 9, 9, 16, 8, 7, 14, 10}, -+ {2060, 9, 35, 9, 9, 9, 16, 8, 7, 14, 10}, -+ {2050, 9, 35, 9, 9, 9, 16, 8, 7, 14, 10}, -+ {2040, 9, 35, 9, 9, 9, 16, 8, 7, 14, 10}, -+ {2030, 9, 35, 9, 9, 9, 16, 8, 7, 13, 10}, -+ {2020, 9, 35, 9, 9, 9, 16, 8, 7, 13, 10}, -+ {2010, 9, 34, 9, 9, 9, 15, 8, 7, 13, 10}, -+ {2000, 9, 34, 8, 9, 9, 15, 8, 7, 13, 10}, -+ {1990, 9, 34, 8, 9, 9, 15, 8, 7, 13, 10}, -+ {1980, 9, 34, 8, 9, 9, 15, 8, 7, 13, 10}, -+ {1970, 9, 33, 8, 9, 9, 15, 8, 7, 13, 10}, -+ {1960, 9, 33, 8, 9, 9, 15, 8, 7, 13, 10}, -+ {1950, 9, 33, 8, 8, 9, 15, 8, 7, 13, 10}, -+ {1940, 9, 33, 8, 8, 9, 15, 8, 7, 13, 10}, -+ {1930, 9, 32, 8, 8, 9, 14, 8, 7, 13, 10}, -+ {1920, 9, 32, 8, 8, 9, 14, 8, 7, 13, 10}, -+ {1910, 9, 32, 8, 8, 8, 15, 7, 7, 13, 9}, -+ {1900, 9, 32, 8, 8, 8, 15, 7, 7, 13, 9}, -+ {1890, 9, 31, 8, 8, 8, 15, 7, 7, 12, 9}, -+ {1880, 8, 32, 8, 8, 8, 15, 7, 7, 12, 9}, -+ {1870, 8, 32, 8, 8, 8, 15, 7, 7, 12, 9}, -+ {1860, 8, 32, 8, 8, 8, 14, 7, 6, 12, 9}, -+ {1850, 8, 32, 8, 8, 8, 14, 7, 6, 12, 9}, -+ {1840, 8, 31, 8, 8, 8, 14, 7, 6, 12, 9}, -+ {1830, 8, 31, 8, 8, 8, 14, 7, 6, 12, 9}, -+ {1820, 8, 31, 8, 8, 8, 14, 7, 6, 12, 9}, -+ {1810, 8, 31, 8, 8, 8, 14, 7, 6, 12, 9}, -+ {1800, 8, 30, 7, 8, 8, 14, 7, 6, 12, 9}, -+ {1790, 8, 30, 7, 8, 8, 13, 7, 6, 12, 9}, -+ {1780, 8, 30, 7, 8, 8, 13, 7, 6, 12, 9}, -+ {1770, 8, 30, 7, 8, 8, 13, 7, 6, 12, 9}, -+ {1760, 8, 29, 7, 8, 8, 13, 7, 6, 12, 9}, -+ {1750, 8, 29, 7, 8, 8, 13, 7, 6, 12, 9}, -+ {1740, 8, 29, 7, 8, 8, 13, 7, 6, 11, 8}, -+ {1730, 8, 29, 7, 8, 8, 13, 7, 6, 11, 8}, -+ {1720, 8, 29, 7, 7, 8, 13, 7, 6, 11, 8}, -+ {1710, 8, 28, 7, 7, 8, 12, 7, 6, 11, 8}, -+ {1700, 8, 28, 7, 7, 7, 13, 7, 6, 11, 8}, -+ {1690, 8, 28, 7, 7, 7, 13, 7, 6, 11, 8}, -+ {1680, 7, 29, 7, 7, 7, 13, 6, 6, 11, 8}, -+ {1670, 7, 28, 7, 7, 7, 13, 6, 6, 11, 8}, -+ {1660, 7, 28, 7, 7, 7, 13, 6, 6, 11, 8}, -+ {1650, 7, 28, 7, 7, 7, 13, 6, 6, 11, 8}, -+ {1640, 7, 28, 7, 7, 7, 12, 6, 6, 11, 8}, -+ {1630, 7, 27, 7, 7, 7, 12, 6, 6, 11, 8}, -+ {1620, 7, 27, 7, 7, 7, 12, 6, 6, 11, 8}, -+ {1610, 7, 27, 7, 7, 7, 12, 6, 6, 11, 8}, -+ {1600, 7, 27, 6, 7, 7, 12, 6, 5, 10, 8}, -+ {1590, 7, 26, 6, 7, 7, 12, 6, 5, 10, 8}, -+ {1580, 7, 26, 6, 7, 7, 12, 6, 5, 10, 7}, -+ {1570, 7, 26, 6, 7, 7, 11, 6, 5, 10, 7}, -+ {1560, 7, 26, 6, 7, 7, 11, 6, 5, 10, 7}, -+ {1550, 7, 26, 6, 7, 7, 11, 6, 5, 10, 7}, -+ {1540, 7, 25, 6, 7, 7, 11, 6, 5, 10, 7}, -+ {1530, 7, 25, 6, 7, 7, 11, 6, 5, 10, 7}, -+ {1520, 7, 25, 6, 7, 7, 11, 6, 5, 10, 7}, -+ {1510, 7, 25, 6, 7, 7, 11, 6, 5, 10, 7}, -+ {1500, 7, 24, 6, 7, 7, 10, 6, 5, 10, 7}, -+ {1490, 59, 25, 6, 77, 59, 10, 70, 44, 9, 73}, -+ {1480, 59, 24, 6, 76, 58, 10, 70, 44, 9, 73}, -+ {1470, 58, 24, 6, 76, 58, 10, 69, 44, 9, 72}, -+ {1460, 58, 24, 6, 76, 58, 10, 69, 43, 9, 72}, -+ {1450, 58, 24, 6, 75, 57, 10, 68, 43, 9, 71}, -+ {1440, 57, 24, 6, 75, 57, 10, 68, 43, 9, 71}, -+ {1430, 57, 23, 6, 75, 57, 10, 68, 43, 8, 70}, -+ {1420, 56, 23, 6, 74, 57, 9, 67, 43, 8, 70}, -+ {1410, 56, 23, 6, 74, 57, 9, 67, 43, 8, 69}, -+ {1400, 56, 23, 5, 74, 55, 9, 67, 41, 8, 69}, -+ {1390, 55, 23, 5, 73, 55, 9, 66, 41, 8, 68}, -+ {1380, 55, 23, 5, 73, 54, 9, 66, 41, 8, 68}, -+ {1370, 54, 22, 5, 72, 54, 9, 66, 41, 8, 67}, -+ {1360, 54, 22, 5, 72, 54, 9, 65, 40, 8, 67}, -+ {1350, 54, 22, 5, 72, 53, 9, 65, 40, 8, 66}, -+ {1340, 53, 22, 5, 71, 53, 9, 65, 40, 8, 66}, -+ {1330, 53, 22, 5, 71, 53, 9, 64, 39, 8, 65}, -+ {1320, 52, 22, 5, 71, 53, 8, 64, 40, 8, 65}, -+ {1310, 52, 21, 5, 70, 53, 8, 64, 40, 8, 64}, -+ {1300, 51, 21, 5, 70, 51, 8, 63, 38, 8, 64}, -+ {1290, 51, 21, 5, 70, 51, 8, 63, 38, 7, 64}, -+ {1280, 51, 21, 5, 69, 51, 8, 63, 38, 7, 63}, -+ {1270, 50, 21, 5, 69, 50, 8, 62, 38, 7, 63}, -+ {1260, 50, 20, 5, 69, 50, 8, 62, 37, 7, 62}, -+ {1250, 49, 20, 5, 68, 49, 8, 62, 37, 7, 62}, -+ {1240, 49, 20, 5, 68, 49, 8, 61, 37, 7, 61}, -+ {1230, 49, 20, 5, 68, 49, 8, 61, 36, 7, 61}, -+ {1220, 48, 20, 5, 67, 48, 8, 61, 36, 7, 60}, -+ {1210, 48, 19, 5, 67, 48, 7, 60, 36, 7, 60}, -+ {1200, 49, 19, 4, 67, 49, 7, 60, 36, 7, 59}, -+ {1190, 48, 19, 4, 66, 48, 7, 60, 36, 7, 59}, -+ {1180, 48, 19, 4, 66, 48, 7, 59, 36, 7, 58}, -+ {1170, 46, 19, 4, 66, 46, 7, 59, 35, 7, 58}, -+ {1160, 46, 18, 4, 65, 46, 7, 59, 34, 7, 57}, -+ {1150, 45, 18, 4, 65, 46, 7, 58, 34, 7, 57}, -+ {1140, 45, 18, 4, 65, 45, 7, 58, 34, 6, 56}, -+ {1130, 45, 18, 4, 64, 45, 7, 58, 33, 6, 56}, -+ {1120, 44, 18, 4, 64, 44, 7, 57, 33, 6, 55}, -+ {1110, 44, 18, 4, 64, 44, 7, 57, 33, 6, 55}, -+ {1100, 43, 17, 4, 63, 44, 6, 57, 32, 6, 54}, -+ {1090, 43, 17, 4, 63, 44, 6, 56, 33, 6, 54}, -+ {1080, 43, 17, 4, 63, 44, 6, 56, 33, 6, 53}, -+ {1070, 42, 17, 4, 62, 44, 6, 56, 33, 6, 53}, -+ {1060, 42, 17, 4, 62, 42, 6, 55, 31, 6, 52}, -+ {1050, 41, 17, 4, 62, 42, 6, 55, 31, 6, 52}, -+ {1040, 41, 16, 4, 61, 41, 6, 54, 31, 6, 52}, -+ {1030, 41, 16, 4, 61, 41, 6, 54, 30, 6, 51}, -+ {1020, 40, 16, 4, 61, 41, 6, 54, 30, 6, 51}, -+ {1010, 40, 16, 4, 60, 40, 6, 53, 30, 6, 50}, -+ {1000, 39, 16, 3, 60, 40, 6, 53, 29, 5, 50}, -+ { 990, 39, 15, 3, 60, 39, 6, 53, 29, 5, 49}, -+ { 980, 39, 15, 3, 59, 39, 5, 52, 29, 5, 49}, -+ { 970, 38, 15, 3, 59, 39, 5, 52, 29, 5, 48}, -+ { 960, 38, 15, 3, 59, 39, 5, 52, 29, 5, 48}, -+ { 950, 37, 15, 3, 58, 39, 5, 51, 29, 5, 47}, -+ { 940, 37, 14, 3, 58, 39, 5, 51, 29, 5, 47}, -+ { 930, 37, 14, 3, 57, 37, 5, 51, 27, 5, 46}, -+ { 920, 36, 14, 3, 57, 37, 5, 50, 27, 5, 46}, -+ { 910, 36, 14, 3, 57, 36, 5, 50, 27, 5, 45}, -+ { 900, 35, 14, 3, 56, 36, 5, 50, 26, 5, 45}, -+ { 890, 35, 14, 3, 56, 36, 5, 49, 26, 5, 44}, -+ { 880, 35, 13, 3, 56, 35, 5, 49, 26, 5, 44}, -+ { 870, 34, 13, 3, 55, 35, 4, 49, 26, 5, 43}, -+ { 860, 34, 13, 3, 55, 35, 4, 48, 25, 5, 43}, -+ { 850, 33, 13, 3, 55, 35, 4, 48, 26, 4, 42}, -+ { 840, 33, 13, 3, 54, 35, 4, 48, 26, 4, 42}, -+ { 830, 33, 12, 3, 54, 33, 4, 47, 24, 4, 41}, -+ { 820, 32, 12, 3, 54, 33, 4, 47, 24, 4, 41}, -+ { 810, 32, 12, 3, 53, 33, 4, 47, 24, 4, 40}, -+ { 800, 31, 12, 2, 53, 32, 4, 46, 23, 4, 40}, -+ { 790, 31, 12, 2, 53, 32, 4, 46, 23, 4, 39}, -+ { 780, 30, 12, 2, 52, 31, 4, 46, 23, 4, 39}, -+ { 770, 30, 11, 2, 52, 31, 4, 45, 23, 4, 39}, -+ { 760, 30, 11, 2, 52, 31, 3, 45, 22, 4, 38}, -+ { 750, 29, 11, 2, 51, 30, 3, 45, 22, 4, 38}, -+ { 740, 29, 11, 2, 51, 30, 3, 44, 22, 4, 37}, -+ { 730, 28, 11, 2, 51, 31, 3, 44, 22, 4, 37}, -+ { 720, 28, 10, 2, 50, 30, 3, 44, 22, 4, 36}, -+ { 710, 28, 10, 2, 50, 30, 3, 43, 22, 4, 36}, -+ { 700, 27, 10, 2, 50, 28, 3, 43, 20, 3, 35}, -+ { 690, 27, 10, 2, 49, 28, 3, 43, 20, 3, 35}, -+ { 680, 26, 10, 2, 49, 28, 3, 42, 20, 3, 34}, -+ { 670, 26, 10, 2, 49, 27, 3, 42, 20, 3, 34}, -+ { 660, 26, 9, 2, 48, 27, 3, 42, 19, 3, 33}, -+ { 650, 25, 9, 2, 48, 26, 3, 41, 19, 3, 33}, -+ { 640, 25, 9, 2, 48, 26, 2, 41, 19, 3, 32}, -+ { 630, 24, 9, 2, 47, 26, 2, 40, 18, 3, 32}, -+ { 620, 24, 9, 2, 47, 26, 2, 40, 19, 3, 31}, -+ { 610, 24, 8, 2, 47, 26, 2, 40, 19, 3, 31}, -+ { 600, 23, 8, 1, 46, 26, 2, 39, 18, 3, 30}, -+ { 590, 23, 8, 1, 46, 24, 2, 39, 17, 3, 30}, -+ { 580, 22, 8, 1, 46, 24, 2, 39, 17, 3, 29}, -+ { 570, 22, 8, 1, 45, 23, 2, 38, 17, 3, 29}, -+ { 560, 22, 7, 1, 45, 23, 2, 38, 16, 2, 28}, -+ { 550, 21, 7, 1, 45, 23, 2, 38, 16, 2, 28}, -+ { 540, 21, 7, 1, 44, 22, 2, 37, 16, 2, 27}, -+ { 530, 20, 7, 1, 44, 22, 1, 37, 15, 2, 27}, -+ { 520, 20, 7, 1, 43, 21, 1, 37, 15, 2, 27}, -+ { 510, 20, 6, 1, 43, 21, 1, 36, 15, 2, 26}, -+ { 500, 19, 6, 1, 43, 22, 1, 36, 15, 2, 26}, -+ { 490, 19, 6, 1, 42, 21, 1, 36, 15, 2, 25}, -+ { 480, 18, 6, 1, 42, 21, 1, 35, 15, 2, 25}, -+ { 470, 18, 6, 1, 42, 21, 1, 35, 15, 2, 24}, -+ { 460, 18, 6, 1, 41, 19, 1, 35, 13, 2, 24}, -+ { 450, 17, 5, 1, 41, 19, 1, 34, 13, 2, 23}, -+ { 440, 17, 5, 1, 41, 18, 1, 34, 13, 2, 23}, -+ { 430, 16, 5, 1, 40, 18, 0, 34, 12, 2, 22}, -+ { 420, 16, 5, 1, 40, 18, 0, 33, 12, 2, 22}, -+ { 410, 16, 5, 1, 40, 17, 0, 33, 12, 1, 21}, -+ { 400, 15, 5, 0, 39, 17, 0, 33, 11, 1, 21}, -+ { 390, 15, 4, 0, 39, 17, 0, 32, 12, 1, 20}, -+ { 380, 14, 4, 0, 39, 17, 0, 32, 12, 1, 20}, -+ { 370, 14, 4, 0, 38, 17, 0, 32, 12, 1, 19}, -+ { 360, 14, 4, 0, 38, 15, 0, 31, 10, 1, 19}, -+ { 350, 13, 4, 0, 38, 15, 0, 31, 10, 1, 18}, -+ { 340, 13, 3, 0, 37, 15, 0, 31, 10, 1, 18}, -+ { 330, 12, 3, 0, 37, 14, 0, 30, 9, 1, 17}, -+ { 320, 12, 3, 0, 37, 14, 0, 30, 9, 1, 17}, -+ { 310, 12, 3, 0, 36, 13, 0, 30, 9, 1, 16}, -+ { 300, 11, 3, 0, 36, 13, 0, 29, 8, 1, 16}, -+ { 290, 11, 2, 0, 36, 13, 0, 29, 8, 1, 15}, -+ { 280, 10, 2, 0, 35, 12, 0, 29, 8, 1, 15}, -+ { 270, 10, 2, 0, 35, 12, 0, 28, 8, 0, 14}, -+ { 260, 9, 2, 0, 35, 12, 0, 28, 8, 0, 14}, -+ { 250, 9, 2, 0, 34, 12, 0, 28, 8, 0, 14}, -+ { 240, 9, 2, 0, 34, 12, 0, 27, 8, 0, 13}, -+ { 230, 8, 1, 0, 34, 10, 0, 27, 6, 0, 13}, -+ { 220, 8, 1, 0, 33, 10, 0, 27, 6, 0, 12}, -+ { 210, 7, 1, 0, 33, 10, 0, 26, 6, 0, 12}, -+ { 200, 7, 1, 0, 33, 9, 0, 26, 5, 0, 11}, -+ { 190, 7, 1, 0, 32, 9, 0, 25, 5, 0, 11}, -+ { 180, 6, 1, 0, 32, 8, 0, 25, 5, 0, 10}, -+ { 170, 6, 0, 0, 32, 8, 0, 25, 5, 0, 10}, -+ { 160, 5, 0, 0, 31, 8, 0, 24, 4, 0, 9}, -+ { 150, 5, 0, 0, 31, 8, 0, 24, 5, 0, 9}, -+ { 140, 5, 0, 0, 31, 8, 0, 24, 5, 0, 8}, -+ { 130, 4, 0, 0, 30, 6, 0, 23, 3, 0, 8}, -+ { 120, 4, 0, 0, 30, 6, 0, 23, 3, 0, 7}, -+ { 110, 3, 0, 0, 30, 6, 0, 23, 3, 0, 7}, -+ { 100, 3, 0, 0, 29, 5, 0, 22, 2, 0, 6}, -+ { 90, 3, 0, 0, 29, 5, 0, 22, 2, 0, 6}, -+ { 80, 2, 0, 0, 28, 5, 0, 22, 2, 0, 5}, -+}; -+ -+struct hsfreq_range { -+ u32 range_h; -+ u16 cfg_bit; -+}; -+ -+/* These tables must be sorted by .range_h ascending. */ -+static const struct hsfreq_range samsung_dphy_rx_hsfreq_ranges[] = { -+ { 80, 0x105}, { 100, 0x106}, { 120, 0x107}, { 140, 0x108}, -+ { 160, 0x109}, { 180, 0x10a}, { 200, 0x10b}, { 220, 0x10c}, -+ { 240, 0x10d}, { 270, 0x10e}, { 290, 0x10f}, { 310, 0x110}, -+ { 330, 0x111}, { 350, 0x112}, { 370, 0x113}, { 390, 0x114}, -+ { 410, 0x115}, { 430, 0x116}, { 450, 0x117}, { 470, 0x118}, -+ { 490, 0x119}, { 510, 0x11a}, { 540, 0x11b}, { 560, 0x11c}, -+ { 580, 0x11d}, { 600, 0x11e}, { 620, 0x11f}, { 640, 0x120}, -+ { 660, 0x121}, { 680, 0x122}, { 700, 0x123}, { 720, 0x124}, -+ { 740, 0x125}, { 760, 0x126}, { 790, 0x127}, { 810, 0x128}, -+ { 830, 0x129}, { 850, 0x12a}, { 870, 0x12b}, { 890, 0x12c}, -+ { 910, 0x12d}, { 930, 0x12e}, { 950, 0x12f}, { 970, 0x130}, -+ { 990, 0x131}, {1010, 0x132}, {1030, 0x133}, {1060, 0x134}, -+ {1080, 0x135}, {1100, 0x136}, {1120, 0x137}, {1140, 0x138}, -+ {1160, 0x139}, {1180, 0x13a}, {1200, 0x13b}, {1220, 0x13c}, -+ {1240, 0x13d}, {1260, 0x13e}, {1280, 0x13f}, {1310, 0x140}, -+ {1330, 0x141}, {1350, 0x142}, {1370, 0x143}, {1390, 0x144}, -+ {1410, 0x145}, {1430, 0x146}, {1450, 0x147}, {1470, 0x148}, -+ {1490, 0x149}, {1580, 0x007}, {1740, 0x008}, {1910, 0x009}, -+ {2070, 0x00a}, {2240, 0x00b}, {2410, 0x00c}, {2570, 0x00d}, -+ {2740, 0x00e}, {2910, 0x00f}, {3070, 0x010}, {3240, 0x011}, -+ {3410, 0x012}, {3570, 0x013}, {3740, 0x014}, {3890, 0x015}, -+ {4070, 0x016}, {4240, 0x017}, {4400, 0x018}, {4500, 0x019}, -+}; -+ -+static void samsung_mipi_dcphy_bias_block_enable(struct samsung_mipi_dcphy *samsung) -+{ -+ u32 bias_con2 = 0x3223; -+ -+ regmap_write(samsung->regmap, BIAS_CON0, 0x0010); -+ regmap_write(samsung->regmap, BIAS_CON1, 0x0110); -+ regmap_write(samsung->regmap, BIAS_CON2, bias_con2); -+ -+ /* output voltage, 400mV for DPHY, 530mV for CPHY */ -+ regmap_update_bits(samsung->regmap, BIAS_CON4, -+ I_MUX_SEL_MASK, I_MUX_SEL_400MV); -+} -+ -+static void samsung_mipi_dcphy_bias_block_disable(struct samsung_mipi_dcphy *samsung) -+{ -+} -+ -+static void samsung_mipi_dphy_lane_enable(struct samsung_mipi_dcphy *samsung) -+{ -+ regmap_write(samsung->regmap, DPHY_MC_GNR_CON1, T_PHY_READY(0x2000)); -+ regmap_update_bits(samsung->regmap, DPHY_MC_GNR_CON0, -+ PHY_ENABLE, PHY_ENABLE); -+ -+ switch (samsung->lanes) { -+ case 4: -+ regmap_write(samsung->regmap, DPHY_MD3_GNR_CON1, -+ T_PHY_READY(0x2000)); -+ regmap_update_bits(samsung->regmap, DPHY_MD3_GNR_CON0, -+ PHY_ENABLE, PHY_ENABLE); -+ fallthrough; -+ case 3: -+ regmap_write(samsung->regmap, COMBO_MD2_GNR_CON1, -+ T_PHY_READY(0x2000)); -+ regmap_update_bits(samsung->regmap, COMBO_MD2_GNR_CON0, -+ PHY_ENABLE, PHY_ENABLE); -+ fallthrough; -+ case 2: -+ regmap_write(samsung->regmap, COMBO_MD1_GNR_CON1, -+ T_PHY_READY(0x2000)); -+ regmap_update_bits(samsung->regmap, COMBO_MD1_GNR_CON0, -+ PHY_ENABLE, PHY_ENABLE); -+ fallthrough; -+ case 1: -+ default: -+ regmap_write(samsung->regmap, COMBO_MD0_GNR_CON1, -+ T_PHY_READY(0x2000)); -+ regmap_update_bits(samsung->regmap, COMBO_MD0_GNR_CON0, -+ PHY_ENABLE, PHY_ENABLE); -+ break; -+ } -+} -+ -+static void samsung_mipi_dphy_lane_disable(struct samsung_mipi_dcphy *samsung) -+{ -+ regmap_update_bits(samsung->regmap, DPHY_MC_GNR_CON0, PHY_ENABLE, 0); -+ regmap_update_bits(samsung->regmap, COMBO_MD0_GNR_CON0, PHY_ENABLE, 0); -+ regmap_update_bits(samsung->regmap, COMBO_MD1_GNR_CON0, PHY_ENABLE, 0); -+ regmap_update_bits(samsung->regmap, COMBO_MD2_GNR_CON0, PHY_ENABLE, 0); -+ regmap_update_bits(samsung->regmap, DPHY_MD3_GNR_CON0, PHY_ENABLE, 0); -+} -+ -+static void samsung_mipi_dcphy_pll_configure(struct samsung_mipi_dcphy *samsung) -+{ -+ regmap_update_bits(samsung->regmap, PLL_CON0, S_MASK | P_MASK, -+ S(samsung->pll.scaler) | P(samsung->pll.prediv)); -+ -+ if (samsung->pll.dsm < 0) { -+ u16 dsm_tmp; -+ -+ /* Using opposite number subtraction to find complement */ -+ dsm_tmp = abs(samsung->pll.dsm); -+ dsm_tmp = dsm_tmp - 1; -+ dsm_tmp ^= 0xffff; -+ regmap_write(samsung->regmap, PLL_CON1, dsm_tmp); -+ } else { -+ regmap_write(samsung->regmap, PLL_CON1, samsung->pll.dsm); -+ } -+ -+ regmap_update_bits(samsung->regmap, PLL_CON2, -+ M_MASK, M(samsung->pll.fbdiv)); -+ -+ if (samsung->pll.ssc_en) { -+ regmap_write(samsung->regmap, PLL_CON3, -+ MRR(samsung->pll.mrr) | MFR(samsung->pll.mfr)); -+ regmap_update_bits(samsung->regmap, PLL_CON4, SSCG_EN, SSCG_EN); -+ } -+ -+ regmap_write(samsung->regmap, PLL_CON5, RESET_N_SEL | PLL_ENABLE_SEL); -+ regmap_write(samsung->regmap, PLL_CON7, PLL_LOCK_CNT(0xf000)); -+ regmap_write(samsung->regmap, PLL_CON8, PLL_STB_CNT(0xf000)); -+} -+ -+static int samsung_mipi_dcphy_pll_enable(struct samsung_mipi_dcphy *samsung) -+{ -+ u32 sts; -+ int ret; -+ -+ regmap_update_bits(samsung->regmap, PLL_CON0, PLL_EN, PLL_EN); -+ -+ ret = regmap_read_poll_timeout(samsung->regmap, PLL_STAT0, -+ sts, (sts & PLL_LOCK), 1000, 20000); -+ if (ret < 0) -+ dev_err(samsung->dev, "DC-PHY pll failed to lock\n"); -+ -+ return ret; -+} -+ -+static void samsung_mipi_dcphy_pll_disable(struct samsung_mipi_dcphy *samsung) -+{ -+ regmap_update_bits(samsung->regmap, PLL_CON0, PLL_EN, 0); -+} -+ -+static const struct samsung_mipi_dphy_timing * -+samsung_mipi_dphy_get_timing(struct samsung_mipi_dcphy *samsung) -+{ -+ const struct samsung_mipi_dphy_timing *timings; -+ unsigned int num_timings; -+ unsigned int lane_mbps = div64_ul(samsung->pll.rate, USEC_PER_SEC); -+ unsigned int i; -+ -+ timings = samsung_mipi_dphy_timing_table; -+ num_timings = ARRAY_SIZE(samsung_mipi_dphy_timing_table); -+ -+ for (i = num_timings; i > 0; i--) -+ if (lane_mbps <= timings[i - 1].max_lane_mbps) -+ break; -+ -+ if (i == 0) -+ ++i; -+ -+ return &timings[i - 1]; -+} -+ -+static unsigned long -+samsung_mipi_dcphy_pll_round_rate(struct samsung_mipi_dcphy *samsung, -+ unsigned long prate, unsigned long rate, -+ u8 *prediv, u16 *fbdiv, int *dsm, u8 *scaler) -+{ -+ u64 max_fout = MAX_DPHY_BW; -+ u64 best_freq = 0; -+ u64 fin, fvco, fout; -+ u8 min_prediv, max_prediv; -+ u8 _prediv, best_prediv = 1; -+ u16 _fbdiv, best_fbdiv = 1; -+ u8 _scaler, best_scaler = 0; -+ u32 min_delta = UINT_MAX; -+ long _dsm, best_dsm = 0; -+ -+ /* -+ * The PLL output frequency can be calculated using a simple formula: -+ * Fvco = ((m+k/65536) x 2 x Fin) / p -+ * Fout = ((m+k/65536) x 2 x Fin) / (p x 2^s) -+ */ -+ fin = div64_ul(prate, MSEC_PER_SEC); -+ -+ while (!best_freq) { -+ fout = div64_ul(rate, MSEC_PER_SEC); -+ if (fout > max_fout) -+ fout = max_fout; -+ -+ /* 0 ≤ S[2:0] ≤ 6 */ -+ for (_scaler = 0; _scaler < 7; _scaler++) { -+ fvco = fout << _scaler; -+ -+ /* -+ * 2600MHz ≤ FVCO ≤ 6600MHz -+ */ -+ if (fvco < 2600 * MSEC_PER_SEC || fvco > 6600 * MSEC_PER_SEC) -+ continue; -+ -+ /* 6MHz ≤ Fref(Fin / p) ≤ 30MHz */ -+ min_prediv = DIV_ROUND_UP_ULL(fin, 30 * MSEC_PER_SEC); -+ max_prediv = DIV_ROUND_CLOSEST_ULL(fin, 6 * MSEC_PER_SEC); -+ -+ for (_prediv = min_prediv; _prediv <= max_prediv; _prediv++) { -+ u64 delta, tmp; -+ -+ _fbdiv = DIV_ROUND_CLOSEST_ULL(fvco * _prediv, 2 * fin); -+ -+ /* 64 ≤ M[9:0] ≤ 1023 */ -+ if (_fbdiv < 64 || _fbdiv > 1023) -+ continue; -+ -+ /* -32767 ≤ K[15:0] ≤ 32767 */ -+ _dsm = ((_prediv * fvco) - (2 * _fbdiv * fin)); -+ _dsm = DIV_ROUND_UP_ULL(_dsm << 15, fin); -+ if (abs(_dsm) > 32767) -+ continue; -+ -+ tmp = DIV_ROUND_CLOSEST_ULL((_fbdiv * fin * 2 * 1000), _prediv); -+ tmp += DIV_ROUND_CLOSEST_ULL((_dsm * fin * 1000), _prediv << 15); -+ -+ delta = abs(fvco * MSEC_PER_SEC - tmp); -+ if (delta < min_delta) { -+ best_prediv = _prediv; -+ best_fbdiv = _fbdiv; -+ best_dsm = _dsm; -+ best_scaler = _scaler; -+ min_delta = delta; -+ best_freq = DIV_ROUND_CLOSEST_ULL(tmp, 1000) * MSEC_PER_SEC; -+ } -+ } -+ } -+ -+ rate += 100 * MSEC_PER_SEC; -+ } -+ -+ *prediv = best_prediv; -+ *fbdiv = best_fbdiv; -+ *dsm = (int)best_dsm & 0xffff; -+ *scaler = best_scaler; -+ dev_dbg(samsung->dev, "p: %d, m: %d, dsm:%ld, scaler: %d\n", -+ best_prediv, best_fbdiv, best_dsm, best_scaler); -+ -+ return best_freq >> best_scaler; -+} -+ -+static void -+samsung_mipi_dphy_clk_lane_timing_init(struct samsung_mipi_dcphy *samsung) -+{ -+ const struct samsung_mipi_dphy_timing *timing; -+ unsigned int lane_hs_rate = div64_ul(samsung->pll.rate, USEC_PER_SEC); -+ u32 val = 0; -+ -+ timing = samsung_mipi_dphy_get_timing(samsung); -+ regmap_write(samsung->regmap, DPHY_MC_GNR_CON0, 0xf000); -+ regmap_write(samsung->regmap, DPHY_MC_ANA_CON0, 0x7133); -+ -+ if (lane_hs_rate >= 4500) -+ regmap_write(samsung->regmap, DPHY_MC_ANA_CON1, 0x0001); -+ -+ /* -+ * Divide-by-2 Clock from Serial Clock. Use this when data rate is under -+ * 1500Mbps, otherwise divide-by-16 Clock from Serial Clock -+ */ -+ if (lane_hs_rate < 1500) -+ val = HSTX_CLK_SEL; -+ -+ val |= T_LPX(timing->lpx); -+ /* T_LP_EXIT_SKEW/T_LP_ENTRY_SKEW unconfig */ -+ regmap_write(samsung->regmap, DPHY_MC_TIME_CON0, val); -+ -+ val = T_CLK_ZERO(timing->clk_zero) | T_CLK_PREPARE(timing->clk_prepare); -+ regmap_write(samsung->regmap, DPHY_MC_TIME_CON1, val); -+ -+ val = T_HS_EXIT(timing->hs_exit) | T_CLK_TRAIL(timing->clk_trail_eot); -+ regmap_write(samsung->regmap, DPHY_MC_TIME_CON2, val); -+ -+ val = T_CLK_POST(timing->clk_post); -+ regmap_write(samsung->regmap, DPHY_MC_TIME_CON3, val); -+ -+ /* Escape Clock is 20.00MHz */ -+ regmap_write(samsung->regmap, DPHY_MC_TIME_CON4, 0x1f4); -+ -+ /* -+ * skew calibration should be off, if the operation data rate is -+ * under 1.5Gbps or equal to 1.5Gbps. -+ */ -+ if (lane_hs_rate > 1500) -+ regmap_write(samsung->regmap, DPHY_MC_DESKEW_CON0, 0x9cb1); -+} -+ -+static void -+samsung_mipi_dphy_data_lane_timing_init(struct samsung_mipi_dcphy *samsung) -+{ -+ const struct samsung_mipi_dphy_timing *timing; -+ unsigned int lane_hs_rate = div64_ul(samsung->pll.rate, USEC_PER_SEC); -+ u32 val = 0; -+ -+ timing = samsung_mipi_dphy_get_timing(samsung); -+ -+ regmap_write(samsung->regmap, COMBO_MD0_ANA_CON0, 0x7133); -+ regmap_write(samsung->regmap, COMBO_MD1_ANA_CON0, 0x7133); -+ regmap_write(samsung->regmap, COMBO_MD2_ANA_CON0, 0x7133); -+ regmap_write(samsung->regmap, DPHY_MD3_ANA_CON0, 0x7133); -+ -+ if (lane_hs_rate >= 4500) { -+ regmap_write(samsung->regmap, COMBO_MD0_ANA_CON1, 0x0001); -+ regmap_write(samsung->regmap, COMBO_MD1_ANA_CON1, 0x0001); -+ regmap_write(samsung->regmap, COMBO_MD2_ANA_CON1, 0x0001); -+ regmap_write(samsung->regmap, DPHY_MD3_ANA_CON1, 0x0001); -+ } -+ -+ /* -+ * Divide-by-2 Clock from Serial Clock. Use this when data rate is under -+ * 1500Mbps, otherwise divide-by-16 Clock from Serial Clock -+ */ -+ if (lane_hs_rate < 1500) -+ val = HSTX_CLK_SEL; -+ -+ val |= T_LPX(timing->lpx); -+ /* T_LP_EXIT_SKEW/T_LP_ENTRY_SKEW unconfig */ -+ regmap_write(samsung->regmap, COMBO_MD0_TIME_CON0, val); -+ regmap_write(samsung->regmap, COMBO_MD1_TIME_CON0, val); -+ regmap_write(samsung->regmap, COMBO_MD2_TIME_CON0, val); -+ regmap_write(samsung->regmap, DPHY_MD3_TIME_CON0, val); -+ -+ val = T_HS_ZERO(timing->hs_zero) | T_HS_PREPARE(timing->hs_prepare); -+ regmap_write(samsung->regmap, COMBO_MD0_TIME_CON1, val); -+ regmap_write(samsung->regmap, COMBO_MD1_TIME_CON1, val); -+ regmap_write(samsung->regmap, COMBO_MD2_TIME_CON1, val); -+ regmap_write(samsung->regmap, DPHY_MD3_TIME_CON1, val); -+ -+ val = T_HS_EXIT(timing->hs_exit) | T_HS_TRAIL(timing->hs_trail_eot); -+ regmap_write(samsung->regmap, COMBO_MD0_TIME_CON2, val); -+ regmap_write(samsung->regmap, COMBO_MD1_TIME_CON2, val); -+ regmap_write(samsung->regmap, COMBO_MD2_TIME_CON2, val); -+ regmap_write(samsung->regmap, DPHY_MD3_TIME_CON2, val); -+ -+ /* TTA-GET/TTA-GO Timing Counter register use default value */ -+ val = T_TA_GET(0x3) | T_TA_GO(0x0); -+ regmap_write(samsung->regmap, COMBO_MD0_TIME_CON3, val); -+ regmap_write(samsung->regmap, COMBO_MD1_TIME_CON3, val); -+ regmap_write(samsung->regmap, COMBO_MD2_TIME_CON3, val); -+ regmap_write(samsung->regmap, DPHY_MD3_TIME_CON3, val); -+ -+ /* Escape Clock is 20.00MHz */ -+ regmap_write(samsung->regmap, COMBO_MD0_TIME_CON4, 0x1f4); -+ regmap_write(samsung->regmap, COMBO_MD1_TIME_CON4, 0x1f4); -+ regmap_write(samsung->regmap, COMBO_MD2_TIME_CON4, 0x1f4); -+ regmap_write(samsung->regmap, DPHY_MD3_TIME_CON4, 0x1f4); -+} -+ -+static int samsung_mipi_dphy_power_on(struct samsung_mipi_dcphy *samsung) -+{ -+ int ret; -+ -+ reset_control_assert(samsung->m_phy_rst); -+ -+ samsung_mipi_dcphy_bias_block_enable(samsung); -+ samsung_mipi_dcphy_pll_configure(samsung); -+ samsung_mipi_dphy_clk_lane_timing_init(samsung); -+ samsung_mipi_dphy_data_lane_timing_init(samsung); -+ ret = samsung_mipi_dcphy_pll_enable(samsung); -+ if (ret < 0) { -+ samsung_mipi_dcphy_bias_block_disable(samsung); -+ return ret; -+ } -+ -+ samsung_mipi_dphy_lane_enable(samsung); -+ -+ reset_control_deassert(samsung->m_phy_rst); -+ -+ /* The TSKEWCAL maximum is 100 µsec -+ * at initial calibration. -+ */ -+ usleep_range(100, 110); -+ -+ return 0; -+} -+ -+static int samsung_mipi_dcphy_power_on(struct phy *phy) -+{ -+ struct samsung_mipi_dcphy *samsung = phy_get_drvdata(phy); -+ enum phy_mode mode = phy_get_mode(phy); -+ -+ pm_runtime_get_sync(samsung->dev); -+ reset_control_assert(samsung->apb_rst); -+ udelay(1); -+ reset_control_deassert(samsung->apb_rst); -+ -+ switch (mode) { -+ case PHY_MODE_MIPI_DPHY: -+ return samsung_mipi_dphy_power_on(samsung); -+ default: -+ /* CSI cphy part to be implemented later */ -+ return -EOPNOTSUPP; -+ } -+ -+ return 0; -+} -+ -+static int samsung_mipi_dcphy_power_off(struct phy *phy) -+{ -+ struct samsung_mipi_dcphy *samsung = phy_get_drvdata(phy); -+ enum phy_mode mode = phy_get_mode(phy); -+ -+ switch (mode) { -+ case PHY_MODE_MIPI_DPHY: -+ samsung_mipi_dphy_lane_disable(samsung); -+ break; -+ default: -+ /* CSI cphy part to be implemented later */ -+ return -EOPNOTSUPP; -+ } -+ -+ samsung_mipi_dcphy_pll_disable(samsung); -+ samsung_mipi_dcphy_bias_block_disable(samsung); -+ -+ pm_runtime_put(samsung->dev); -+ -+ return 0; -+} -+ -+static int samsung_mipi_dcphy_set_mode(struct phy *phy, enum phy_mode mode, -+ int submode) -+{ -+ return 0; -+} -+ -+static int -+samsung_mipi_dcphy_pll_ssc_modulation_calc(struct samsung_mipi_dcphy *samsung, -+ u8 *mfr, u8 *mrr) -+{ -+ unsigned long fin = div64_ul(clk_get_rate(samsung->ref_clk), MSEC_PER_SEC); -+ u16 prediv = samsung->pll.prediv; -+ u16 fbdiv = samsung->pll.fbdiv; -+ u16 min_mfr, max_mfr; -+ u16 _mfr, best_mfr = 0; -+ u16 mr, _mrr, best_mrr = 0; -+ -+ /* 20KHz ≤ MF ≤ 150KHz */ -+ max_mfr = DIV_ROUND_UP(fin, (20 * prediv) << 5); -+ min_mfr = div64_ul(fin, ((150 * prediv) << 5)); -+ /*0 ≤ mfr ≤ 255 */ -+ if (max_mfr > 256) -+ max_mfr = 256; -+ -+ for (_mfr = min_mfr; _mfr < max_mfr; _mfr++) { -+ /* 1 ≤ mrr ≤ 31 */ -+ for (_mrr = 1; _mrr < 32; _mrr++) { -+ mr = DIV_ROUND_UP(_mfr * _mrr * 100, fbdiv << 6); -+ /* 0 ≤ MR ≤ 5% */ -+ if (mr > 5) -+ continue; -+ -+ if (_mfr * _mrr < 513) { -+ best_mfr = _mfr; -+ best_mrr = _mrr; -+ break; -+ } -+ } -+ } -+ -+ if (best_mrr) { -+ *mfr = best_mfr & 0xff; -+ *mrr = best_mrr & 0x3f; -+ } else { -+ dev_err(samsung->dev, "failed to calc ssc parameter mfr and mrr\n"); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static void -+samsung_mipi_dcphy_pll_calc_rate(struct samsung_mipi_dcphy *samsung, -+ unsigned long long rate) -+{ -+ unsigned long prate = clk_get_rate(samsung->ref_clk); -+ unsigned long fout; -+ u8 scaler = 0, mfr = 0, mrr = 0; -+ u16 fbdiv = 1; -+ u8 prediv = 1; -+ int dsm = 0; -+ int ret; -+ -+ fout = samsung_mipi_dcphy_pll_round_rate(samsung, prate, rate, -+ &prediv, &fbdiv, &dsm, -+ &scaler); -+ -+ dev_dbg(samsung->dev, "%s: fin=%lu, req_rate=%llu\n", -+ __func__, prate, rate); -+ dev_dbg(samsung->dev, "%s: fout=%lu, prediv=%u, fbdiv=%u\n", -+ __func__, fout, prediv, fbdiv); -+ -+ samsung->pll.prediv = prediv; -+ samsung->pll.fbdiv = fbdiv; -+ samsung->pll.dsm = dsm; -+ samsung->pll.scaler = scaler; -+ samsung->pll.rate = fout; -+ -+ /* -+ * All DPHY 2.0 compliant Transmitters shall support SSC operating above -+ * 2.5 Gbps -+ */ -+ if (fout > 2500000000LL) { -+ ret = samsung_mipi_dcphy_pll_ssc_modulation_calc(samsung, -+ &mfr, &mrr); -+ if (!ret) { -+ samsung->pll.ssc_en = true; -+ samsung->pll.mfr = mfr; -+ samsung->pll.mrr = mrr; -+ } -+ } -+} -+ -+static int samsung_mipi_dcphy_configure(struct phy *phy, -+ union phy_configure_opts *opts) -+{ -+ struct samsung_mipi_dcphy *samsung = phy_get_drvdata(phy); -+ unsigned long long target_rate = opts->mipi_dphy.hs_clk_rate; -+ -+ samsung->lanes = opts->mipi_dphy.lanes > 4 ? 4 : opts->mipi_dphy.lanes; -+ -+ samsung_mipi_dcphy_pll_calc_rate(samsung, target_rate); -+ opts->mipi_dphy.hs_clk_rate = samsung->pll.rate; -+ -+ return 0; -+} -+ -+static int samsung_mipi_dcphy_init(struct phy *phy) -+{ -+ struct samsung_mipi_dcphy *samsung = phy_get_drvdata(phy); -+ -+ pm_runtime_get_sync(samsung->dev); -+ -+ return 0; -+} -+ -+static int samsung_mipi_dcphy_exit(struct phy *phy) -+{ -+ struct samsung_mipi_dcphy *samsung = phy_get_drvdata(phy); -+ -+ pm_runtime_put(samsung->dev); -+ -+ return 0; -+} -+ -+static const struct phy_ops samsung_mipi_dcphy_ops = { -+ .configure = samsung_mipi_dcphy_configure, -+ .set_mode = samsung_mipi_dcphy_set_mode, -+ .power_on = samsung_mipi_dcphy_power_on, -+ .power_off = samsung_mipi_dcphy_power_off, -+ .init = samsung_mipi_dcphy_init, -+ .exit = samsung_mipi_dcphy_exit, -+ .owner = THIS_MODULE, -+}; -+ -+static const struct regmap_config samsung_mipi_dcphy_regmap_config = { -+ .name = "dcphy", -+ .reg_bits = 32, -+ .val_bits = 32, -+ .reg_stride = 4, -+ .max_register = 0x10000, -+}; -+ -+static int samsung_mipi_dcphy_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct device_node *np = dev->of_node; -+ struct samsung_mipi_dcphy *samsung; -+ struct phy_provider *phy_provider; -+ struct phy *phy; -+ struct resource *res; -+ void __iomem *regs; -+ int ret; -+ -+ samsung = devm_kzalloc(dev, sizeof(*samsung), GFP_KERNEL); -+ if (!samsung) -+ return -ENOMEM; -+ -+ samsung->dev = dev; -+ platform_set_drvdata(pdev, samsung); -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ regs = devm_ioremap_resource(dev, res); -+ if (IS_ERR(regs)) -+ return PTR_ERR(regs); -+ -+ samsung->regmap = devm_regmap_init_mmio(dev, regs, -+ &samsung_mipi_dcphy_regmap_config); -+ if (IS_ERR(samsung->regmap)) { -+ ret = PTR_ERR(samsung->regmap); -+ dev_err(dev, "failed to init regmap: %d\n", ret); -+ return ret; -+ } -+ -+ samsung->grf_regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); -+ if (IS_ERR(samsung->grf_regmap)) { -+ dev_err(dev, "Unable to get rockchip,grf\n"); -+ return PTR_ERR(samsung->grf_regmap); -+ } -+ -+ samsung->ref_clk = devm_clk_get(dev, "ref"); -+ if (IS_ERR(samsung->ref_clk)) { -+ dev_err(dev, "failed to get reference clock\n"); -+ return PTR_ERR(samsung->ref_clk); -+ } -+ -+ samsung->pclk = devm_clk_get(dev, "pclk"); -+ if (IS_ERR(samsung->pclk)) { -+ dev_err(dev, "failed to get pclk\n"); -+ return PTR_ERR(samsung->pclk); -+ } -+ -+ samsung->m_phy_rst = devm_reset_control_get(dev, "m_phy"); -+ if (IS_ERR(samsung->m_phy_rst)) { -+ dev_err(dev, "failed to get system m_phy_rst control\n"); -+ return PTR_ERR(samsung->m_phy_rst); -+ } -+ -+ samsung->s_phy_rst = devm_reset_control_get(dev, "s_phy"); -+ if (IS_ERR(samsung->s_phy_rst)) { -+ dev_err(dev, "failed to get system s_phy_rst control\n"); -+ return PTR_ERR(samsung->s_phy_rst); -+ } -+ -+ samsung->apb_rst = devm_reset_control_get(dev, "apb"); -+ if (IS_ERR(samsung->apb_rst)) { -+ dev_err(dev, "failed to get system apb_rst control\n"); -+ return PTR_ERR(samsung->apb_rst); -+ } -+ -+ samsung->grf_apb_rst = devm_reset_control_get(dev, "grf"); -+ if (IS_ERR(samsung->grf_apb_rst)) { -+ dev_err(dev, "failed to get system grf_apb_rst control\n"); -+ return PTR_ERR(samsung->grf_apb_rst); -+ } -+ -+ phy = devm_phy_create(dev, NULL, &samsung_mipi_dcphy_ops); -+ if (IS_ERR(phy)) { -+ dev_err(dev, "failed to create MIPI Dc-PHY\n"); -+ return PTR_ERR(phy); -+ } -+ -+ phy_set_drvdata(phy, samsung); -+ -+ ret = devm_pm_runtime_enable(dev); -+ if (ret) -+ return dev_err_probe(dev, ret, "Failed to enable runtime PM\n"); -+ -+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); -+ if (IS_ERR(phy_provider)) { -+ dev_err(dev, "failed to register phy provider\n"); -+ return PTR_ERR(phy_provider); -+ } -+ -+ return 0; -+} -+ -+static __maybe_unused int samsung_mipi_dcphy_runtime_suspend(struct device *dev) -+{ -+ struct samsung_mipi_dcphy *samsung = dev_get_drvdata(dev); -+ -+ clk_disable_unprepare(samsung->pclk); -+ clk_disable_unprepare(samsung->ref_clk); -+ -+ return 0; -+} -+ -+static __maybe_unused int samsung_mipi_dcphy_runtime_resume(struct device *dev) -+{ -+ struct samsung_mipi_dcphy *samsung = dev_get_drvdata(dev); -+ -+ clk_prepare_enable(samsung->pclk); -+ clk_prepare_enable(samsung->ref_clk); -+ -+ return 0; -+} -+ -+static const struct dev_pm_ops samsung_mipi_dcphy_pm_ops = { -+ RUNTIME_PM_OPS(samsung_mipi_dcphy_runtime_suspend, -+ samsung_mipi_dcphy_runtime_resume, NULL) -+}; -+ -+static const struct of_device_id samsung_mipi_dcphy_of_match[] = { -+ { -+ .compatible = "rockchip,rk3588-mipi-dcphy", -+ }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, samsung_mipi_dcphy_of_match); -+ -+static struct platform_driver samsung_mipi_dcphy_driver = { -+ .driver = { -+ .name = "samsung-mipi-dcphy", -+ .of_match_table = of_match_ptr(samsung_mipi_dcphy_of_match), -+ .pm = &samsung_mipi_dcphy_pm_ops, -+ }, -+ .probe = samsung_mipi_dcphy_probe, -+}; -+module_platform_driver(samsung_mipi_dcphy_driver); -+ -+MODULE_AUTHOR("Guochun Huang<hero.huang@rock-chips.com>"); -+MODULE_DESCRIPTION("Samsung MIPI DCPHY Driver"); -+MODULE_LICENSE("GPL"); diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/5002-rk3588-dsi-dts-nodes.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/5002-rk3588-dsi-dts-nodes.patch deleted file mode 100644 index 65cd119b7d..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/5002-rk3588-dsi-dts-nodes.patch +++ /dev/null @@ -1,133 +0,0 @@ -commit 1eaa2d3617ff73b514383f9c197fa5557b04a923 -Author: Lukas F. Hartmann <lukas@mntre.com> -Date: Thu Aug 8 18:47:15 2024 +0200 - - rk3588: dtsi: add dsi0/1 and mipidcphy0/1 nodes - - Co-authored-by: Heiko Stuebner <heiko.stuebner@cherry.de> - ---- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi -@@ -580,6 +580,16 @@ - reg = <0x0 0xfd58c000 0x0 0x1000>; - }; - -+ mipidcphy0_grf: syscon@fd5e8000 { -+ compatible = "rockchip,rk3588-dcphy-grf", "syscon"; -+ reg = <0x0 0xfd5e8000 0x0 0x4000>; -+ }; -+ -+ mipidcphy1_grf: syscon@fd5ec000 { -+ compatible = "rockchip,rk3588-dcphy-grf", "syscon"; -+ reg = <0x0 0xfd5ec000 0x0 0x4000>; -+ }; -+ - vop_grf: syscon@fd5a4000 { - compatible = "rockchip,rk3588-vop-grf", "syscon"; - reg = <0x0 0xfd5a4000 0x0 0x2000>; -@@ -1410,6 +1420,66 @@ - status = "disabled"; - }; - -+ dsi0: dsi@fde20000 { -+ compatible = "rockchip,rk3588-mipi-dsi2"; -+ reg = <0x0 0xfde20000 0x0 0x10000>; -+ interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH 0>; -+ clocks = <&cru PCLK_DSIHOST0>, <&cru CLK_DSIHOST0>; -+ clock-names = "pclk", "sys_clk"; -+ resets = <&cru SRST_P_DSIHOST0>; -+ reset-names = "apb"; -+ power-domains = <&power RK3588_PD_VOP>; -+ phys = <&mipidcphy0>; -+ phy-names = "dcphy"; -+ rockchip,grf = <&vop_grf>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ dsi0_in: port@0 { -+ reg = <0>; -+ }; -+ -+ dsi0_out: port@1 { -+ reg = <1>; -+ }; -+ }; -+ }; -+ -+ dsi1: dsi@fde30000 { -+ compatible = "rockchip,rk3588-mipi-dsi2"; -+ reg = <0x0 0xfde30000 0x0 0x10000>; -+ interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH 0>; -+ clocks = <&cru PCLK_DSIHOST1>, <&cru CLK_DSIHOST1>; -+ clock-names = "pclk", "sys_clk"; -+ resets = <&cru SRST_P_DSIHOST1>; -+ reset-names = "apb"; -+ power-domains = <&power RK3588_PD_VOP>; -+ phys = <&mipidcphy1>; -+ phy-names = "dcphy"; -+ rockchip,grf = <&vop_grf>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ dsi1_in: port@0 { -+ reg = <0>; -+ }; -+ -+ dsi1_out: port@1 { -+ reg = <1>; -+ }; -+ }; -+ }; -+ - hdmi0: hdmi@fde80000 { - compatible = "rockchip,rk3588-dw-hdmi-qp"; - reg = <0x0 0xfde80000 0x0 0x20000>; -@@ -2957,6 +3027,38 @@ - status = "disabled"; - }; - -+ mipidcphy0: phy@feda0000 { -+ compatible = "rockchip,rk3588-mipi-dcphy"; -+ reg = <0x0 0xfeda0000 0x0 0x10000>; -+ rockchip,grf = <&mipidcphy0_grf>; -+ clocks = <&cru PCLK_MIPI_DCPHY0>, -+ <&cru CLK_USBDPPHY_MIPIDCPPHY_REF>; -+ clock-names = "pclk", "ref"; -+ resets = <&cru SRST_M_MIPI_DCPHY0>, -+ <&cru SRST_P_MIPI_DCPHY0>, -+ <&cru SRST_P_MIPI_DCPHY0_GRF>, -+ <&cru SRST_S_MIPI_DCPHY0>; -+ reset-names = "m_phy", "apb", "grf", "s_phy"; -+ #phy-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ mipidcphy1: phy@fedb0000 { -+ compatible = "rockchip,rk3588-mipi-dcphy"; -+ reg = <0x0 0xfedb0000 0x0 0x10000>; -+ rockchip,grf = <&mipidcphy1_grf>; -+ clocks = <&cru PCLK_MIPI_DCPHY1>, -+ <&cru CLK_USBDPPHY_MIPIDCPPHY_REF>; -+ clock-names = "pclk", "ref"; -+ resets = <&cru SRST_M_MIPI_DCPHY1>, -+ <&cru SRST_P_MIPI_DCPHY1>, -+ <&cru SRST_P_MIPI_DCPHY1_GRF>, -+ <&cru SRST_S_MIPI_DCPHY1>; -+ reset-names = "m_phy", "apb", "grf", "s_phy"; -+ #phy-cells = <0>; -+ status = "disabled"; -+ }; -+ - combphy0_ps: phy@fee00000 { - compatible = "rockchip,rk3588-naneng-combphy"; - reg = <0x0 0xfee00000 0x0 0x100>; diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/5100-modernize-hdmi1-in-dtsi.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/5100-modernize-hdmi1-in-dtsi.patch deleted file mode 100644 index ebbce00b15..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/5100-modernize-hdmi1-in-dtsi.patch +++ /dev/null @@ -1,43 +0,0 @@ -diff --git a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi -index ad34951..1ffbf13 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi -@@ -1522,7 +1522,7 @@ hdmi0_out: port@1 { - }; - - hdmi1: hdmi@fdea0000 { -- compatible = "rockchip,rk3588-dw-hdmi"; -+ compatible = "rockchip,rk3588-dw-hdmi-qp"; - reg = <0x0 0xfdea0000 0x0 0x20000>; - interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH 0>, - <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH 0>, -@@ -1534,27 +1534,19 @@ hdmi1: hdmi@fdea0000 { - <&cru CLK_HDMITX1_EARC>, - <&cru CLK_HDMITX1_REF>, - <&cru MCLK_I2S6_8CH_TX>, -- <&cru DCLK_VOP0>, -- <&cru DCLK_VOP1>, -- <&cru DCLK_VOP2>, -- <&cru DCLK_VOP3>, - <&cru HCLK_VO1>; - clock-names = "pclk", - "hpd", - "earc", -- "hdmitx_ref", -+ "ref", - "aud", -- "dclk_vp0", -- "dclk_vp1", -- "dclk_vp2", -- "dclk_vp3", - "hclk_vo1"; - - resets = <&cru SRST_HDMITX1_REF>, <&cru SRST_HDMIHDP1>; - reset-names = "ref", "hdp"; - power-domains = <&power RK3588_PD_VO1>; - pinctrl-names = "default"; -- pinctrl-0 = <&hdmim2_tx1_cec &hdmim0_tx1_hpd &hdmim1_tx1_scl &hdmim1_tx1_sda>; -+ pinctrl-0 = <&hdmim2_tx1_cec &hdmim1_tx1_hpd &hdmim1_tx1_scl &hdmim1_tx1_sda>; - reg-io-width = <4>; - rockchip,grf = <&sys_grf>; - rockchip,vo1_grf = <&vo1_grf>; diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/5110-hdptx-crash-workaround.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/5110-hdptx-crash-workaround.patch deleted file mode 100644 index 2669e7b6c5..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/5110-hdptx-crash-workaround.patch +++ /dev/null @@ -1,51 +0,0 @@ ---- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c -+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c -@@ -1482,7 +1482,10 @@ static int rk_hdptx_phy_runtime_suspend( - { - struct rk_hdptx_phy *hdptx = dev_get_drvdata(dev); - -- dev_dbg(hdptx->dev, "suspend\n"); -+ if (WARN_ON(!hdptx)) -+ return -EBUSY; -+ if (WARN_ON(!hdptx->dev)) -+ return -EBUSY; - - clk_bulk_disable_unprepare(hdptx->nr_clks, hdptx->clks); - -@@ -1494,7 +1497,12 @@ static int rk_hdptx_phy_runtime_resume(s - struct rk_hdptx_phy *hdptx = dev_get_drvdata(dev); - int ret; - -- dev_dbg(hdptx->dev, "resume\n"); -+ dev_err(dev, "[DEBUG rk_hdptx_phy_runtime_resume] called\n"); -+ -+ if (WARN_ON(!hdptx)) -+ return -EBUSY; -+ if (WARN_ON(!hdptx->dev)) -+ return -EBUSY; - - ret = clk_bulk_prepare_enable(hdptx->nr_clks, hdptx->clks); - if (ret) -@@ -1556,16 +1564,18 @@ static int rk_hdptx_phy_probe(struct pla - - platform_set_drvdata(pdev, hdptx); - -- ret = devm_pm_runtime_enable(dev); -- if (ret) -- return dev_err_probe(dev, ret, "Failed to enable runtime PM\n"); -- - hdptx->phy = devm_phy_create(dev, NULL, &rk_hdptx_phy_ops); - if (IS_ERR(hdptx->phy)) - return dev_err_probe(dev, PTR_ERR(hdptx->phy), - "Failed to create HDMI PHY\n"); - - phy_set_drvdata(hdptx->phy, hdptx); -+ -+ dev_err(dev, "[DEBUG rk_hdptx_phy_probe] phy_set_drvdata done, about to devm_pm_runtime_enable\n"); -+ ret = devm_pm_runtime_enable(dev); -+ if (ret) -+ return dev_err_probe(dev, ret, "Failed to enable runtime PM\n"); -+ - phy_set_bus_width(hdptx->phy, 8); - - phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); diff --git a/gnu/packages/patches/reform/rk3588-mnt-reform2/5200-drm-rockchip-Set-dma-mask-to-64-bit.patch b/gnu/packages/patches/reform/rk3588-mnt-reform2/5200-drm-rockchip-Set-dma-mask-to-64-bit.patch deleted file mode 100644 index 0871b841ee..0000000000 --- a/gnu/packages/patches/reform/rk3588-mnt-reform2/5200-drm-rockchip-Set-dma-mask-to-64-bit.patch +++ /dev/null @@ -1,105 +0,0 @@ -From mboxrd@z Thu Jan 1 00:00:00 1970 -Received: from m16.mail.163.com (m16.mail.163.com [117.135.210.5]) - by smtp.subspace.kernel.org (Postfix) with ESMTP id 29D24770FE; - Fri, 20 Sep 2024 08:21:10 +0000 (UTC) -Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=117.135.210.5 -ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; - t=1726820473; cv=none; b=LePs8DGLBCSPTiNkkQPZa3HzWmFnMwxeSuYcmqzFLof18Em5C5GfQjFjmLGWjtcphnNv3ejsgbXqZiZYTxQx77wCUGf4WTipBpPNkoK68bWMYw2QkMT7uUYHVbhSreqYJg0FWZU6IpHBK3/BY23HmPX6GefLGDM5FCSVpA90h/Q= -ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; - s=arc-20240116; t=1726820473; c=relaxed/simple; - bh=ryHQMHCPPZJodfqNIYsZ85GCvifO/TIN92/nFcCWRvY=; - h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: - MIME-Version; b=gIeWxkfgTF2XIR63L9c46uC1ZFFYr3Zv01itmqy7lqxUommXwI3DWp2n1kABgoL6JGPsZPMlOSreK7ZYH437eZtUTjAEenlrgHYYIIm0GHANznyBsvudH5hJb/S/S05/gZGBR4miUlzySsRwtMqXXY8fM0KhSlSnpqdHrNU0mwU= -ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com; spf=pass smtp.mailfrom=163.com; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b=Ms/OpU2x; arc=none smtp.client-ip=117.135.210.5 -Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com -Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=163.com -Authentication-Results: smtp.subspace.kernel.org; - dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b="Ms/OpU2x" -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; - s=s110527; h=From:Subject:Date:Message-ID:MIME-Version; bh=GBq4X - 3SvjcKdAw76+LCZ96Aeae4FkXSnYqiBRPXZuM4=; b=Ms/OpU2xi0lF+5s6ABh2o - yW/zFVMA64LbYDTSwaf8EpKAuzQzwpnTPAZF2sZv/aDKCbf4B0mbFz80m0BJLE0a - Pd6MftUJWeiep/YPfLfiEDyVnfBX6AX6tdjSa4ZXqTm5D6znQLto6ceTurcepa0T - iARi+8b9tBdYiKKv6gjbx0= -Received: from ProDesk.. (unknown [58.22.7.114]) - by gzga-smtp-mta-g3-0 (Coremail) with SMTP id _____wCnL3ZVMO1mBh1QBg--.6466S2; - Fri, 20 Sep 2024 16:20:40 +0800 (CST) -From: Andy Yan <andyshrk@163.com> -To: heiko@sntech.de -Cc: hjc@rock-chips.com, - krzk+dt@kernel.org, - robh@kernel.org, - conor+dt@kernel.org, - s.hauer@pengutronix.de, - devicetree@vger.kernel.org, - dri-devel@lists.freedesktop.org, - linux-arm-kernel@lists.infradead.org, - linux-kernel@vger.kernel.org, - linux-rockchip@lists.infradead.org, - derek.foreman@collabora.com, - minhuadotchen@gmail.com, - detlev.casanova@collabora.com, - Andy Yan <andy.yan@rock-chips.com> -Subject: [PATCH v3 02/15] drm/rockchip: Set dma mask to 64 bit -Date: Fri, 20 Sep 2024 16:20:23 +0800 -Message-ID: <20240920082036.6623-1-andyshrk@163.com> -X-Mailer: git-send-email 2.43.0 -In-Reply-To: <20240920081626.6433-1-andyshrk@163.com> -References: <20240920081626.6433-1-andyshrk@163.com> -Precedence: bulk -X-Mailing-List: linux-kernel@vger.kernel.org -List-Id: <linux-kernel.vger.kernel.org> -List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org> -List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org> -MIME-Version: 1.0 -Content-Transfer-Encoding: 8bit -X-CM-TRANSID:_____wCnL3ZVMO1mBh1QBg--.6466S2 -X-Coremail-Antispam: 1Uf129KBjvJXoW7CF1xur1rJr1fWF13GFWUtwb_yoW8WFWfp3 - s0kFZrKrW8GayDXFWjkFsxAF45Kw1vya17G343JwnxJw17Krn8A3ZI9FyDt3y3Jr1xC3Wa - yrsxKrWI9Fs2vr7anT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 - 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07jFT5dUUUUU= -X-CM-SenderInfo: 5dqg52xkunqiywtou0bp/xtbB0h5gXmWX0hsr2QAAs7 - -From: Andy Yan <andy.yan@rock-chips.com> - -The vop mmu support translate physical address upper 4 GB to iova -below 4 GB. So set dma mask to 64 bit to indicate we support address -> 4GB. - -This can avoid warnging message like this on some boards with DDR -> 4 GB: - -rockchip-drm display-subsystem: swiotlb buffer is full (sz: 266240 bytes), total 32768 (slots), used 130 (slots) -rockchip-drm display-subsystem: swiotlb buffer is full (sz: 266240 bytes), total 32768 (slots), used 0 (slots) -rockchip-drm display-subsystem: swiotlb buffer is full (sz: 266240 bytes), total 32768 (slots), used 130 (slots) -rockchip-drm display-subsystem: swiotlb buffer is full (sz: 266240 bytes), total 32768 (slots), used 130 (slots) -rockchip-drm display-subsystem: swiotlb buffer is full (sz: 266240 bytes), total 32768 (slots), used 0 (slots) - -Signed-off-by: Andy Yan <andy.yan@rock-chips.com> -Tested-by: Derek Foreman <derek.foreman@collabora.com> ---- - -(no changes since v1) - - drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c -index 04ef7a2c3833..8bc2ff3b04bb 100644 ---- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c -+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c -@@ -445,7 +445,9 @@ static int rockchip_drm_platform_probe(struct platform_device *pdev) - return ret; - } - -- return 0; -+ ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(64)); -+ -+ return ret; - } - - static void rockchip_drm_platform_remove(struct platform_device *pdev) --- -2.34.1 - - |