From 29566a8832a42f3f70391ed595414c249a50a06e Mon Sep 17 00:00:00 2001
From: Petr Hodina <phodina@protonmail.com>
Date: Tue, 13 Dec 2022 09:52:26 +0100
Subject: [PATCH 1/5] gnu: Add linux-libre-arm64-amlogic.
* gnu/packages/linux.scm (linux-libre-arm64-amlogic): New variable.
* gnu/local.mk: Add patches.
* gnu/packages/patches/amlogic-0001-LOCAL-set-meson-gx-cma-pool-to-896MB.patch
* gnu/packages/patches/amlogic-0002-LOCAL-set-meson-g12-cma-pool-to-896MB.patch
* gnu/packages/patches/amlogic-0003-LOCAL-arm64-fix-Kodi-sysinfo-CPU-information.patch
* gnu/packages/patches/amlogic-0004-LOCAL-arm64-meson-add-Amlogic-Meson-GX-PM-Suspend.patch
* gnu/packages/patches/amlogic-0005-LOCAL-arm64-dts-meson-add-support-for-GX-PM-and-Virt.patch
* gnu/packages/patches/amlogic-0006-LOCAL-arm64-dts-meson-add-rtc-vrtc-aliases-to-Khadas.patch
* gnu/packages/patches/amlogic-0007-LOCAL-arm64-dts-meson-add-rtc-vrtc-aliases-to-Khadas.patch
* gnu/packages/patches/amlogic-0008-LOCAL-arm64-dts-meson-add-rtc-vrtc-aliases-to-Minix-.patch
* gnu/packages/patches/amlogic-0009-LOCAL-ALSA-Assign-internal-PCM-chmap-ELD-IEC958-kctl.patch
* gnu/packages/patches/amlogic-0010-LOCAL-usb-hub-disable-autosuspend-for-Genesys-Logic-.patch
* gnu/packages/patches/amlogic-0011-LOCAL-of-partial-revert-of-fdt.c-changes.patch
* gnu/packages/patches/amlogic-0012-FROMGIT-drm-lima-Fix-opp-clkname-setting-in-case-of-.patch
* gnu/packages/patches/amlogic-0013-FROMGIT-6.1-dt-bindings-arm-amlogic-add-Beelink-GT1-.patch
* gnu/packages/patches/amlogic-0014-FROMGIT-6.1-arm64-dts-meson-add-support-for-Beelink-.patch
* gnu/packages/patches/amlogic-0015-FROMLIST-v2-arm64-dts-meson-make-dts-use-gpio-fan-ma.patch
* gnu/packages/patches/amlogic-0016-FROMLIST-v1-mmc-meson-gx-fix-deferred-probing.patch
* gnu/packages/patches/amlogic-0017-FROMLIST-v5-dt-bindings-vendor-prefixes-Add-Titan-Mi.patch
* gnu/packages/patches/amlogic-0018-FROMLIST-v5-dt-bindings-auxdisplay-Add-Titan-Micro-E.patch
* gnu/packages/patches/amlogic-0019-FROMLIST-v5-docs-ABI-document-tm1628-attribute-displ.patch
* gnu/packages/patches/amlogic-0020-FROMLIST-v5-auxdisplay-add-support-for-Titanmec-TM16.patch
* gnu/packages/patches/amlogic-0021-FROMLIST-v5-arm64-dts-meson-gxl-s905w-tx3-mini-add-s.patch
* gnu/packages/patches/amlogic-0022-FROMLIST-v5-MAINTAINERS-Add-entry-for-tm1628-auxdisp.patch
* gnu/packages/patches/amlogic-0023-FROMLIST-v1-drm-bridge-dw_hdmi-fix-preference-of-RGB.patch
* gnu/packages/patches/amlogic-0024-WIP-ASoC-hdmi-codec-reorder-channel-allocation-list.patch
* gnu/packages/patches/amlogic-0025-WIP-mmc-meson-gx-mmc-set-core-clock-phase-to-270-deg.patch
* gnu/packages/patches/amlogic-0026-WIP-arm64-dts-meson-add-Broadcom-WiFi-to-P212-dtsi.patch
* gnu/packages/patches/amlogic-0027-WIP-arm64-dts-meson-move-pwm_ef-node-in-P212-dtsi.patch
* gnu/packages/patches/amlogic-0028-WIP-arm64-dts-meson-remove-WiFi-BT-nodes-from-Khadas.patch
* gnu/packages/patches/amlogic-0029-WIP-arm64-dts-meson-set-p212-p23x-q20x-SDIO-to-100MH.patch
* gnu/packages/patches/amlogic-0030-WIP-arm64-dts-meson-add-UHS-SDIO-capabilities-to-p21.patch
* gnu/packages/patches/amlogic-0031-WIP-arm64-dts-meson-remove-SDIO-node-from-Khadas-VIM.patch
* gnu/packages/patches/amlogic-0032-WIP-arm64-dts-meson-add-audio-playback-to-S905X-P212.patch
* gnu/packages/patches/amlogic-0033-WIP-drivers-meson-vdec-remove-redundant-if-statement.patch
* gnu/packages/patches/amlogic-0034-WIP-drivers-meson-vdec-improve-mmu-and-fbc-handling-.patch
* gnu/packages/patches/amlogic-0035-WIP-drivers-meson-vdec-add-HEVC-decode-codec.patch
* gnu/packages/patches/amlogic-0036-WIP-drivers-meson-vdec-add-handling-to-HEVC-decoder-.patch
* gnu/packages/patches/amlogic-0037-WIP-drivers-meson-vdec-add-HEVC-support-to-GXBB.patch
* gnu/packages/patches/amlogic-0038-WIP-drivers-meson-vdec-check-if-parser-has-really-pa.patch
* gnu/packages/patches/amlogic-0039-WIP-arm64-dts-meson-radxa-zero-add-support-for-the-u.patch
* gnu/packages/patches/amlogic-0040-WIP-dt-bindings-arm-amlogic-add-support-for-Radxa-Ze.patch
* gnu/packages/patches/amlogic-0041-WIP-arm64-dts-meson-add-support-for-Radxa-Zero2.patch
* gnu/packages/patches/amlogic-0042-WIP-arm64-dts-meson-add-audio-playback-to-p201.patch
* gnu/packages/patches/amlogic-0043-WIP-arm64-dts-meson-add-audio-playback-to-p200.patch
* gnu/packages/patches/amlogic-0044-WIP-arm64-dts-meson-add-audio-playback-to-u200.patch
* gnu/packages/patches/amlogic-0045-WIP-arm64-dts-meson-add-Headphone-output-to-Beelink-.patch
* gnu/packages/patches/amlogic-0046-WIP-dt-bindings-arm-amlogic-add-support-for-the-Tani.patch
* gnu/packages/patches/amlogic-0047-WIP-arm64-dts-meson-add-support-for-the-Tanix-TX5-Ma.patch
* gnu/packages/patches/amlogic-0048-WIP-arm64-dts-meson-add-multiple-MeCool-device-trees.patch
* gnu/packages/patches/amlogic-0049-WIP-dt-bindings-arm-amlogic-add-support-for-Minix-NE.patch
* gnu/packages/patches/amlogic-0050-WIP-arm64-dts-meson-add-initial-device-tree-for-Mini.patch
* gnu/packages/patches/amlogic-0051-LOCAL-arm64-dts-meson-add-rtc-vrtc-aliases-to-Minix-.patch
* gnu/packages/patches/amlogic-0052-WIP-media-rc-add-keymap-for-Beelink-Mini-MXIII-remot.patch
* gnu/packages/patches/amlogic-0053-WIP-dt-bindings-arm-amlogic-add-support-for-Beelink-.patch
* gnu/packages/patches/amlogic-0054-WIP-arm64-dts-meson-add-support-for-Beelink-Mini-MXI.patch
* gnu/packages/patches/amlogic-0055-WIP-media-rc-add-keymap-for-MeCool-M8S-Pro-W-remote.patch
* gnu/packages/patches/amlogic-0056-WIP-dt-bindings-arm-amlogic-add-support-for-MeCool-M.patch
* gnu/packages/patches/amlogic-0057-WIP-arm64-dts-meson-add-support-for-MeCool-M8S-Pro-W.patch
* gnu/packages/patches/amlogic-0058-WIP-dt-bindings-arm-amlogic-add-Vero-4K-binding.patch
* gnu/packages/patches/amlogic-0059-WIP-arm64-dts-meson-add-support-for-OSMC-Vero-4K.patch
* gnu/packages/patches/amlogic-0060-WIP-arm64-dts-meson-add-RTL8822CS-bluetooth-to-X96-A.patch
* gnu/packages/patches/amlogic-0061-WIP-media-rc-add-keymap-for-Venz-V10-remote.patch
* gnu/packages/patches/amlogic-0062-WIP-dt-bindings-arm-amlogic-add-S905L-and-Venz-V10-b.patch
* gnu/packages/patches/amlogic-0063-WIP-arm64-dts-meson-add-support-for-Venz-V10.patch
* gnu/packages/patches/amlogic-0064-WIP-dt-bindings-vendor-prefixes-add-tbee-prefix.patch
* gnu/packages/patches/amlogic-0065-WIP-dt-bindings-arm-amlogic-add-TBee-Box-binding.patch
* gnu/packages/patches/amlogic-0066-WIP-arm64-dts-meson-add-support-for-TBee-Box.patch
* gnu/packages/patches/amlogic-0067-WIP-dt-bindings-arm-amlogic-add-Beelink-GT1-binding.patch
* gnu/packages/patches/amlogic-0068-WIP-arm64-dts-meson-add-support-for-Beelink-GT1.patch
* gnu/packages/patches/amlogic-0069-WIP-arm64-dts-meson-add-vcc_5v-regulator-to-WeTek-dt.patch
* gnu/packages/patches/amlogic-0070-WIP-arm64-dts-meson-add-audio-lineout-to-WeTek-Play2.patch
* gnu/packages/patches/amlogic-0071-WIP-arm64-dts-amlogic-fix-cvbs-disable-on-WeTek-Hub.patch
* gnu/packages/patches/amlogic-0072-WIP-ASoC-dt-bindings-add-compatible-for-es8323-i2c.patch
* gnu/packages/patches/amlogic-0073-WIP-ASoC-codecs-add-support-for-ES8323.patch
@@ -876,6 +876,79 @@ dist_patch_DATA = \
%D%/packages/patches/akonadi-paths.patch \
%D%/packages/patches/akonadi-not-relocatable.patch \
%D%/packages/patches/akonadi-timestamps.patch \
+ %D%/packages/patches/amlogic-0001-LOCAL-set-meson-gx-cma-pool-to-896MB.patch \
+ %D%/packages/patches/amlogic-0002-LOCAL-set-meson-g12-cma-pool-to-896MB.patch \
+ %D%/packages/patches/amlogic-0003-LOCAL-arm64-fix-Kodi-sysinfo-CPU-information.patch \
+ %D%/packages/patches/amlogic-0004-LOCAL-arm64-meson-add-Amlogic-Meson-GX-PM-Suspend.patch \
+ %D%/packages/patches/amlogic-0005-LOCAL-arm64-dts-meson-add-support-for-GX-PM-and-Virt.patch \
+ %D%/packages/patches/amlogic-0006-LOCAL-arm64-dts-meson-add-rtc-vrtc-aliases-to-Khadas.patch \
+ %D%/packages/patches/amlogic-0007-LOCAL-arm64-dts-meson-add-rtc-vrtc-aliases-to-Khadas.patch \
+ %D%/packages/patches/amlogic-0008-LOCAL-arm64-dts-meson-add-rtc-vrtc-aliases-to-Minix-.patch \
+ %D%/packages/patches/amlogic-0009-LOCAL-ALSA-Assign-internal-PCM-chmap-ELD-IEC958-kctl.patch \
+ %D%/packages/patches/amlogic-0010-LOCAL-usb-hub-disable-autosuspend-for-Genesys-Logic-.patch \
+ %D%/packages/patches/amlogic-0011-LOCAL-of-partial-revert-of-fdt.c-changes.patch \
+ %D%/packages/patches/amlogic-0012-FROMGIT-drm-lima-Fix-opp-clkname-setting-in-case-of-.patch \
+ %D%/packages/patches/amlogic-0013-FROMGIT-6.1-dt-bindings-arm-amlogic-add-Beelink-GT1-.patch \
+ %D%/packages/patches/amlogic-0014-FROMGIT-6.1-arm64-dts-meson-add-support-for-Beelink-.patch \
+ %D%/packages/patches/amlogic-0015-FROMLIST-v2-arm64-dts-meson-make-dts-use-gpio-fan-ma.patch \
+ %D%/packages/patches/amlogic-0016-FROMLIST-v1-mmc-meson-gx-fix-deferred-probing.patch \
+ %D%/packages/patches/amlogic-0017-FROMLIST-v5-dt-bindings-vendor-prefixes-Add-Titan-Mi.patch \
+ %D%/packages/patches/amlogic-0018-FROMLIST-v5-dt-bindings-auxdisplay-Add-Titan-Micro-E.patch \
+ %D%/packages/patches/amlogic-0019-FROMLIST-v5-docs-ABI-document-tm1628-attribute-displ.patch \
+ %D%/packages/patches/amlogic-0020-FROMLIST-v5-auxdisplay-add-support-for-Titanmec-TM16.patch \
+ %D%/packages/patches/amlogic-0021-FROMLIST-v5-arm64-dts-meson-gxl-s905w-tx3-mini-add-s.patch \
+ %D%/packages/patches/amlogic-0022-FROMLIST-v5-MAINTAINERS-Add-entry-for-tm1628-auxdisp.patch \
+ %D%/packages/patches/amlogic-0023-FROMLIST-v1-drm-bridge-dw_hdmi-fix-preference-of-RGB.patch \
+ %D%/packages/patches/amlogic-0024-WIP-ASoC-hdmi-codec-reorder-channel-allocation-list.patch \
+ %D%/packages/patches/amlogic-0025-WIP-mmc-meson-gx-mmc-set-core-clock-phase-to-270-deg.patch \
+ %D%/packages/patches/amlogic-0026-WIP-arm64-dts-meson-add-Broadcom-WiFi-to-P212-dtsi.patch \
+ %D%/packages/patches/amlogic-0027-WIP-arm64-dts-meson-move-pwm_ef-node-in-P212-dtsi.patch \
+ %D%/packages/patches/amlogic-0028-WIP-arm64-dts-meson-remove-WiFi-BT-nodes-from-Khadas.patch \
+ %D%/packages/patches/amlogic-0029-WIP-arm64-dts-meson-set-p212-p23x-q20x-SDIO-to-100MH.patch \
+ %D%/packages/patches/amlogic-0030-WIP-arm64-dts-meson-add-UHS-SDIO-capabilities-to-p21.patch \
+ %D%/packages/patches/amlogic-0031-WIP-arm64-dts-meson-remove-SDIO-node-from-Khadas-VIM.patch \
+ %D%/packages/patches/amlogic-0032-WIP-arm64-dts-meson-add-audio-playback-to-S905X-P212.patch \
+ %D%/packages/patches/amlogic-0033-WIP-drivers-meson-vdec-remove-redundant-if-statement.patch \
+ %D%/packages/patches/amlogic-0034-WIP-drivers-meson-vdec-improve-mmu-and-fbc-handling-.patch \
+ %D%/packages/patches/amlogic-0035-WIP-drivers-meson-vdec-add-HEVC-decode-codec.patch \
+ %D%/packages/patches/amlogic-0036-WIP-drivers-meson-vdec-add-handling-to-HEVC-decoder-.patch \
+ %D%/packages/patches/amlogic-0037-WIP-drivers-meson-vdec-add-HEVC-support-to-GXBB.patch \
+ %D%/packages/patches/amlogic-0038-WIP-drivers-meson-vdec-check-if-parser-has-really-pa.patch \
+ %D%/packages/patches/amlogic-0039-WIP-arm64-dts-meson-radxa-zero-add-support-for-the-u.patch \
+ %D%/packages/patches/amlogic-0040-WIP-dt-bindings-arm-amlogic-add-support-for-Radxa-Ze.patch \
+ %D%/packages/patches/amlogic-0041-WIP-arm64-dts-meson-add-support-for-Radxa-Zero2.patch \
+ %D%/packages/patches/amlogic-0042-WIP-arm64-dts-meson-add-audio-playback-to-p201.patch \
+ %D%/packages/patches/amlogic-0043-WIP-arm64-dts-meson-add-audio-playback-to-p200.patch \
+ %D%/packages/patches/amlogic-0044-WIP-arm64-dts-meson-add-audio-playback-to-u200.patch \
+ %D%/packages/patches/amlogic-0045-WIP-arm64-dts-meson-add-Headphone-output-to-Beelink-.patch \
+ %D%/packages/patches/amlogic-0046-WIP-dt-bindings-arm-amlogic-add-support-for-the-Tani.patch \
+ %D%/packages/patches/amlogic-0047-WIP-arm64-dts-meson-add-support-for-the-Tanix-TX5-Ma.patch \
+ %D%/packages/patches/amlogic-0048-WIP-arm64-dts-meson-add-multiple-MeCool-device-trees.patch \
+ %D%/packages/patches/amlogic-0049-WIP-dt-bindings-arm-amlogic-add-support-for-Minix-NE.patch \
+ %D%/packages/patches/amlogic-0050-WIP-arm64-dts-meson-add-initial-device-tree-for-Mini.patch \
+ %D%/packages/patches/amlogic-0051-LOCAL-arm64-dts-meson-add-rtc-vrtc-aliases-to-Minix-.patch \
+ %D%/packages/patches/amlogic-0052-WIP-media-rc-add-keymap-for-Beelink-Mini-MXIII-remot.patch \
+ %D%/packages/patches/amlogic-0053-WIP-dt-bindings-arm-amlogic-add-support-for-Beelink-.patch \
+ %D%/packages/patches/amlogic-0054-WIP-arm64-dts-meson-add-support-for-Beelink-Mini-MXI.patch \
+ %D%/packages/patches/amlogic-0055-WIP-media-rc-add-keymap-for-MeCool-M8S-Pro-W-remote.patch \
+ %D%/packages/patches/amlogic-0056-WIP-dt-bindings-arm-amlogic-add-support-for-MeCool-M.patch \
+ %D%/packages/patches/amlogic-0057-WIP-arm64-dts-meson-add-support-for-MeCool-M8S-Pro-W.patch \
+ %D%/packages/patches/amlogic-0058-WIP-dt-bindings-arm-amlogic-add-Vero-4K-binding.patch \
+ %D%/packages/patches/amlogic-0059-WIP-arm64-dts-meson-add-support-for-OSMC-Vero-4K.patch \
+ %D%/packages/patches/amlogic-0060-WIP-arm64-dts-meson-add-RTL8822CS-bluetooth-to-X96-A.patch \
+ %D%/packages/patches/amlogic-0061-WIP-media-rc-add-keymap-for-Venz-V10-remote.patch \
+ %D%/packages/patches/amlogic-0062-WIP-dt-bindings-arm-amlogic-add-S905L-and-Venz-V10-b.patch \
+ %D%/packages/patches/amlogic-0063-WIP-arm64-dts-meson-add-support-for-Venz-V10.patch \
+ %D%/packages/patches/amlogic-0064-WIP-dt-bindings-vendor-prefixes-add-tbee-prefix.patch \
+ %D%/packages/patches/amlogic-0065-WIP-dt-bindings-arm-amlogic-add-TBee-Box-binding.patch \
+ %D%/packages/patches/amlogic-0066-WIP-arm64-dts-meson-add-support-for-TBee-Box.patch \
+ %D%/packages/patches/amlogic-0067-WIP-dt-bindings-arm-amlogic-add-Beelink-GT1-binding.patch \
+ %D%/packages/patches/amlogic-0068-WIP-arm64-dts-meson-add-support-for-Beelink-GT1.patch \
+ %D%/packages/patches/amlogic-0069-WIP-arm64-dts-meson-add-vcc_5v-regulator-to-WeTek-dt.patch \
+ %D%/packages/patches/amlogic-0070-WIP-arm64-dts-meson-add-audio-lineout-to-WeTek-Play2.patch \
+ %D%/packages/patches/amlogic-0071-WIP-arm64-dts-amlogic-fix-cvbs-disable-on-WeTek-Hub.patch \
+ %D%/packages/patches/amlogic-0072-WIP-ASoC-dt-bindings-add-compatible-for-es8323-i2c.patch \
+ %D%/packages/patches/amlogic-0073-WIP-ASoC-codecs-add-support-for-ES8323.patch \
%D%/packages/patches/allegro-mesa-18.2.5-and-later.patch \
%D%/packages/patches/anki-mpv-args.patch \
%D%/packages/patches/antiword-CVE-2014-8123.patch \
@@ -1286,6 +1286,90 @@ (define-public linux-libre-arm64-generic
("CONFIG_SND_SOC_ES8316" . m))
%default-extra-linux-options)))
+(define-public linux-libre-arm64-amlogic
+ (package
+ (inherit linux-libre-arm64-generic)
+ (source (origin
+ (inherit (package-source linux-libre-arm64-generic))
+ ;; Patches from https://github.com/chewitt/LibreELEC.tv.git
+ ;; branch origin/amlogic-upstream
+ ;; commit 38506614e64563cc70be87fe3762d18d49be21d4
+ (patches (append (search-patches
+"amlogic-0001-LOCAL-set-meson-gx-cma-pool-to-896MB.patch"
+"amlogic-0002-LOCAL-set-meson-g12-cma-pool-to-896MB.patch"
+"amlogic-0003-LOCAL-arm64-fix-Kodi-sysinfo-CPU-information.patch"
+"amlogic-0004-LOCAL-arm64-meson-add-Amlogic-Meson-GX-PM-Suspend.patch"
+"amlogic-0005-LOCAL-arm64-dts-meson-add-support-for-GX-PM-and-Virt.patch"
+"amlogic-0006-LOCAL-arm64-dts-meson-add-rtc-vrtc-aliases-to-Khadas.patch"
+"amlogic-0007-LOCAL-arm64-dts-meson-add-rtc-vrtc-aliases-to-Khadas.patch"
+"amlogic-0008-LOCAL-arm64-dts-meson-add-rtc-vrtc-aliases-to-Minix-.patch"
+"amlogic-0009-LOCAL-ALSA-Assign-internal-PCM-chmap-ELD-IEC958-kctl.patch"
+"amlogic-0010-LOCAL-usb-hub-disable-autosuspend-for-Genesys-Logic-.patch"
+"amlogic-0011-LOCAL-of-partial-revert-of-fdt.c-changes.patch"
+"amlogic-0013-FROMGIT-6.1-dt-bindings-arm-amlogic-add-Beelink-GT1-.patch"
+"amlogic-0014-FROMGIT-6.1-arm64-dts-meson-add-support-for-Beelink-.patch"
+"amlogic-0015-FROMLIST-v2-arm64-dts-meson-make-dts-use-gpio-fan-ma.patch"
+"amlogic-0016-FROMLIST-v1-mmc-meson-gx-fix-deferred-probing.patch"
+"amlogic-0017-FROMLIST-v5-dt-bindings-vendor-prefixes-Add-Titan-Mi.patch"
+"amlogic-0018-FROMLIST-v5-dt-bindings-auxdisplay-Add-Titan-Micro-E.patch"
+"amlogic-0019-FROMLIST-v5-docs-ABI-document-tm1628-attribute-displ.patch"
+"amlogic-0020-FROMLIST-v5-auxdisplay-add-support-for-Titanmec-TM16.patch"
+"amlogic-0021-FROMLIST-v5-arm64-dts-meson-gxl-s905w-tx3-mini-add-s.patch"
+"amlogic-0022-FROMLIST-v5-MAINTAINERS-Add-entry-for-tm1628-auxdisp.patch"
+"amlogic-0023-FROMLIST-v1-drm-bridge-dw_hdmi-fix-preference-of-RGB.patch"
+"amlogic-0024-WIP-ASoC-hdmi-codec-reorder-channel-allocation-list.patch"
+"amlogic-0025-WIP-mmc-meson-gx-mmc-set-core-clock-phase-to-270-deg.patch"
+"amlogic-0026-WIP-arm64-dts-meson-add-Broadcom-WiFi-to-P212-dtsi.patch"
+"amlogic-0027-WIP-arm64-dts-meson-move-pwm_ef-node-in-P212-dtsi.patch"
+"amlogic-0028-WIP-arm64-dts-meson-remove-WiFi-BT-nodes-from-Khadas.patch"
+"amlogic-0029-WIP-arm64-dts-meson-set-p212-p23x-q20x-SDIO-to-100MH.patch"
+"amlogic-0030-WIP-arm64-dts-meson-add-UHS-SDIO-capabilities-to-p21.patch"
+"amlogic-0031-WIP-arm64-dts-meson-remove-SDIO-node-from-Khadas-VIM.patch"
+"amlogic-0032-WIP-arm64-dts-meson-add-audio-playback-to-S905X-P212.patch"
+"amlogic-0033-WIP-drivers-meson-vdec-remove-redundant-if-statement.patch"
+"amlogic-0034-WIP-drivers-meson-vdec-improve-mmu-and-fbc-handling-.patch"
+"amlogic-0035-WIP-drivers-meson-vdec-add-HEVC-decode-codec.patch"
+"amlogic-0036-WIP-drivers-meson-vdec-add-handling-to-HEVC-decoder-.patch"
+"amlogic-0037-WIP-drivers-meson-vdec-add-HEVC-support-to-GXBB.patch"
+"amlogic-0038-WIP-drivers-meson-vdec-check-if-parser-has-really-pa.patch"
+"amlogic-0039-WIP-arm64-dts-meson-radxa-zero-add-support-for-the-u.patch"
+"amlogic-0040-WIP-dt-bindings-arm-amlogic-add-support-for-Radxa-Ze.patch"
+"amlogic-0041-WIP-arm64-dts-meson-add-support-for-Radxa-Zero2.patch"
+"amlogic-0042-WIP-arm64-dts-meson-add-audio-playback-to-p201.patch"
+"amlogic-0043-WIP-arm64-dts-meson-add-audio-playback-to-p200.patch"
+"amlogic-0044-WIP-arm64-dts-meson-add-audio-playback-to-u200.patch"
+"amlogic-0045-WIP-arm64-dts-meson-add-Headphone-output-to-Beelink-.patch"
+"amlogic-0046-WIP-dt-bindings-arm-amlogic-add-support-for-the-Tani.patch"
+"amlogic-0047-WIP-arm64-dts-meson-add-support-for-the-Tanix-TX5-Ma.patch"
+"amlogic-0048-WIP-arm64-dts-meson-add-multiple-MeCool-device-trees.patch"
+"amlogic-0049-WIP-dt-bindings-arm-amlogic-add-support-for-Minix-NE.patch"
+"amlogic-0050-WIP-arm64-dts-meson-add-initial-device-tree-for-Mini.patch"
+"amlogic-0051-LOCAL-arm64-dts-meson-add-rtc-vrtc-aliases-to-Minix-.patch"
+"amlogic-0052-WIP-media-rc-add-keymap-for-Beelink-Mini-MXIII-remot.patch"
+"amlogic-0053-WIP-dt-bindings-arm-amlogic-add-support-for-Beelink-.patch"
+"amlogic-0054-WIP-arm64-dts-meson-add-support-for-Beelink-Mini-MXI.patch"
+"amlogic-0055-WIP-media-rc-add-keymap-for-MeCool-M8S-Pro-W-remote.patch"
+"amlogic-0056-WIP-dt-bindings-arm-amlogic-add-support-for-MeCool-M.patch"
+"amlogic-0057-WIP-arm64-dts-meson-add-support-for-MeCool-M8S-Pro-W.patch"
+"amlogic-0058-WIP-dt-bindings-arm-amlogic-add-Vero-4K-binding.patch"
+"amlogic-0059-WIP-arm64-dts-meson-add-support-for-OSMC-Vero-4K.patch"
+"amlogic-0060-WIP-arm64-dts-meson-add-RTL8822CS-bluetooth-to-X96-A.patch"
+"amlogic-0061-WIP-media-rc-add-keymap-for-Venz-V10-remote.patch"
+"amlogic-0062-WIP-dt-bindings-arm-amlogic-add-S905L-and-Venz-V10-b.patch"
+"amlogic-0063-WIP-arm64-dts-meson-add-support-for-Venz-V10.patch"
+"amlogic-0064-WIP-dt-bindings-vendor-prefixes-add-tbee-prefix.patch"
+"amlogic-0065-WIP-dt-bindings-arm-amlogic-add-TBee-Box-binding.patch"
+"amlogic-0066-WIP-arm64-dts-meson-add-support-for-TBee-Box.patch"
+"amlogic-0067-WIP-dt-bindings-arm-amlogic-add-Beelink-GT1-binding.patch"
+"amlogic-0068-WIP-arm64-dts-meson-add-support-for-Beelink-GT1.patch"
+"amlogic-0069-WIP-arm64-dts-meson-add-vcc_5v-regulator-to-WeTek-dt.patch"
+"amlogic-0070-WIP-arm64-dts-meson-add-audio-lineout-to-WeTek-Play2.patch"
+"amlogic-0071-WIP-arm64-dts-amlogic-fix-cvbs-disable-on-WeTek-Hub.patch"
+"amlogic-0072-WIP-ASoC-dt-bindings-add-compatible-for-es8323-i2c.patch"
+"amlogic-0073-WIP-ASoC-codecs-add-support-for-ES8323.patch")
+ (origin-patches (package-source
+ linux-libre-arm64-generic))))))))
+
(define-public linux-libre-arm64-generic-5.10
(make-linux-libre* linux-libre-5.10-version
linux-libre-5.10-gnu-revision
new file mode 100644
@@ -0,0 +1,28 @@
+From bbbc1a8a588a2f899c67941f054dfeb250233a19 Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Sat, 13 Apr 2019 05:41:51 +0000
+Subject: [PATCH 01/73] LOCAL: set meson-gx cma pool to 896MB
+
+This change sets the CMA pool to a larger 896MB! value for vdec use
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
+index 023a52005494..ca0d1733d515 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
++++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
+@@ -58,7 +58,7 @@
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+- size = <0x0 0x10000000>;
++ size = <0x0 0x38000000>;
+ alignment = <0x0 0x400000>;
+ linux,cma-default;
+ };
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,28 @@
+From 391e4a8fc138daf6fba77392eb6ebe688f2f6468 Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Wed, 14 Aug 2019 19:58:14 +0000
+Subject: [PATCH 02/73] LOCAL: set meson-g12 cma pool to 896MB
+
+This change sets the CMA pool to a larger 896MB! value for vdec use
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
+index 45947c1031c4..2c56b216d6f9 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
++++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
+@@ -116,7 +116,7 @@
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+- size = <0x0 0x10000000>;
++ size = <0x0 0x38000000>;
+ alignment = <0x0 0x400000>;
+ linux,cma-default;
+ };
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,31 @@
+From b0f2464452ed2c0cf69e2dee5a1c054fa1b0e6cc Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Sat, 13 Apr 2019 05:45:18 +0000
+Subject: [PATCH 03/73] LOCAL: arm64: fix Kodi sysinfo CPU information
+
+This allows the CPU information to show in the Kodi sysinfo screen, e.g.
+
+"ARMv8 Processor rev 4 (v81)" on Amlogic devices
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ arch/arm64/kernel/cpuinfo.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
+index d7702f39b4d3..4b6ac49e34b4 100644
+--- a/arch/arm64/kernel/cpuinfo.c
++++ b/arch/arm64/kernel/cpuinfo.c
+@@ -169,8 +169,7 @@ static int c_show(struct seq_file *m, void *v)
+ * "processor". Give glibc what it expects.
+ */
+ seq_printf(m, "processor\t: %d\n", i);
+- if (compat)
+- seq_printf(m, "model name\t: ARMv8 Processor rev %d (%s)\n",
++ seq_printf(m, "model name\t: ARMv8 Processor rev %d (%s)\n",
+ MIDR_REVISION(midr), COMPAT_ELF_PLATFORM);
+
+ seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,135 @@
+From d0e70c5cf59999273d7f25ac7153f959a9f12f42 Mon Sep 17 00:00:00 2001
+From: Neil Armstrong <narmstrong@baylibre.com>
+Date: Thu, 3 Nov 2016 15:29:23 +0100
+Subject: [PATCH 04/73] LOCAL: arm64: meson: add Amlogic Meson GX PM Suspend
+
+The Amlogic Meson GX SoCs uses a non-standard argument to the
+PSCI CPU_SUSPEND call to enter system suspend.
+
+Implement such call within platform_suspend_ops.
+
+Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
+---
+ drivers/firmware/meson/Kconfig | 6 ++
+ drivers/firmware/meson/Makefile | 1 +
+ drivers/firmware/meson/meson_gx_pm.c | 86 ++++++++++++++++++++++++++++
+ 3 files changed, 93 insertions(+)
+ create mode 100644 drivers/firmware/meson/meson_gx_pm.c
+
+diff --git a/drivers/firmware/meson/Kconfig b/drivers/firmware/meson/Kconfig
+index f2fdd3756648..d3ead92ac61b 100644
+--- a/drivers/firmware/meson/Kconfig
++++ b/drivers/firmware/meson/Kconfig
+@@ -9,3 +9,9 @@ config MESON_SM
+ depends on ARM64_4K_PAGES
+ help
+ Say y here to enable the Amlogic secure monitor driver
++
++config MESON_GX_PM
++ bool
++ default ARCH_MESON if ARM64
++ help
++ Say y here to enable the Amlogic GX SoC Power Management
+diff --git a/drivers/firmware/meson/Makefile b/drivers/firmware/meson/Makefile
+index c6c09483b622..0193cdfee32f 100644
+--- a/drivers/firmware/meson/Makefile
++++ b/drivers/firmware/meson/Makefile
+@@ -1,2 +1,3 @@
+ # SPDX-License-Identifier: GPL-2.0-only
+ obj-$(CONFIG_MESON_SM) += meson_sm.o
++obj-$(CONFIG_MESON_GX_PM) += meson_gx_pm.o
+diff --git a/drivers/firmware/meson/meson_gx_pm.c b/drivers/firmware/meson/meson_gx_pm.c
+new file mode 100644
+index 000000000000..c104c2e4c77f
+--- /dev/null
++++ b/drivers/firmware/meson/meson_gx_pm.c
+@@ -0,0 +1,86 @@
++/*
++ * Amlogic Meson GX Power Management
++ *
++ * Copyright (c) 2016 Baylibre, SAS.
++ * Author: Neil Armstrong <narmstrong@baylibre.com>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of version 2 of the GNU General Public License as
++ * published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
++ * more details.
++ */
++
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/platform_device.h>
++#include <linux/suspend.h>
++#include <linux/arm-smccc.h>
++
++#include <uapi/linux/psci.h>
++
++#include <asm/suspend.h>
++
++/*
++ * The Amlogic GX SoCs uses a special argument value to the
++ * PSCI CPU_SUSPEND method to enter SUSPEND_MEM.
++ */
++
++#define MESON_SUSPEND_PARAM 0x0010000
++#define PSCI_FN_NATIVE(version, name) PSCI_##version##_FN64_##name
++
++static int meson_gx_suspend_finish(unsigned long arg)
++{
++ struct arm_smccc_res res;
++
++ arm_smccc_smc(PSCI_FN_NATIVE(0_2, CPU_SUSPEND), arg,
++ virt_to_phys(cpu_resume), 0, 0, 0, 0, 0, &res);
++
++ return res.a0;
++}
++
++static int meson_gx_suspend_enter(suspend_state_t state)
++{
++ switch (state) {
++ case PM_SUSPEND_MEM:
++ return cpu_suspend(MESON_SUSPEND_PARAM,
++ meson_gx_suspend_finish);
++ }
++
++ return -EINVAL;
++}
++
++static const struct platform_suspend_ops meson_gx_pm_ops = {
++ .enter = meson_gx_suspend_enter,
++ .valid = suspend_valid_only_mem,
++};
++
++static const struct of_device_id meson_gx_pm_match[] = {
++ { .compatible = "amlogic,meson-gx-pm", },
++ { /* sentinel */ },
++};
++MODULE_DEVICE_TABLE(of, meson_gx_pm_match);
++
++static int meson_gx_pm_probe(struct platform_device *pdev)
++{
++ suspend_set_ops(&meson_gx_pm_ops);
++
++ return 0;
++}
++
++static struct platform_driver meson_gx_pm_driver = {
++ .probe = meson_gx_pm_probe,
++ .driver = {
++ .name = "meson-gx-pm",
++ .of_match_table = meson_gx_pm_match,
++ },
++};
++
++module_platform_driver(meson_gx_pm_driver);
++
++MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
++MODULE_DESCRIPTION("Amlogic Meson GX PM driver");
++MODULE_LICENSE("GPL v2");
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,41 @@
+From 482d13486412a6b33ceb9e64c87e6394942834e9 Mon Sep 17 00:00:00 2001
+From: Neil Armstrong <narmstrong@baylibre.com>
+Date: Thu, 3 Nov 2016 15:29:25 +0100
+Subject: [PATCH 05/73] LOCAL: arm64: dts: meson: add support for GX PM and
+ Virtual RTC
+
+Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
+---
+ arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
+index ca0d1733d515..b278a8380f8a 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
++++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
+@@ -221,6 +221,10 @@
+ };
+ };
+
++ system-suspend {
++ compatible = "amlogic,meson-gx-pm";
++ };
++
+ efuse: efuse {
+ compatible = "amlogic,meson-gx-efuse", "amlogic,meson-gxbb-efuse";
+ #address-cells = <1>;
+@@ -459,6 +463,11 @@
+ };
+ };
+
++ vrtc: rtc@a8 {
++ compatible = "amlogic,meson-vrtc";
++ reg = <0x0 0x000a8 0x0 0x4>;
++ };
++
+ cec_AO: cec@100 {
+ compatible = "amlogic,meson-gx-ao-cec";
+ reg = <0x0 0x00100 0x0 0x14>;
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,30 @@
+From 411cb7102c7addd30d31b41f21471d57df8e2124 Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Thu, 21 Jan 2021 01:35:36 +0000
+Subject: [PATCH 06/73] LOCAL: arm64: dts: meson: add rtc/vrtc aliases to
+ Khadas VIM
+
+Add aliases to ensure the vrtc time (which normally proves first) is /dev/rtc1
+while the onboard rtc chip claims /dev/rtc0.
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
+index 6ab1cc125b96..24af15e18026 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
+@@ -29,6 +29,8 @@
+ aliases {
+ serial2 = &uart_AO_B;
+ ethernet0 = ðmac;
++ rtc0 = &rtc;
++ rtc1 = &vrtc;
+ };
+
+ gpio-keys-polled {
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,30 @@
+From 1786033be020b8a5ab6a86646135e8df2e294524 Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Sat, 6 Nov 2021 13:01:08 +0000
+Subject: [PATCH 07/73] LOCAL: arm64: dts: meson: add rtc/vrtc aliases to
+ Khadas VIM2
+
+Add aliases to ensure the vrtc time (which normally proves first) is /dev/rtc1
+while the onboard rtc chip claims /dev/rtc0.
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts
+index f43c45daf7eb..6d396c1be3d6 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts
++++ b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts
+@@ -18,6 +18,8 @@
+ aliases {
+ serial0 = &uart_AO;
+ serial2 = &uart_AO_B;
++ rtc0 = &rtc;
++ rtc1 = &vrtc;
+ };
+
+ chosen {
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,32 @@
+From eae65baf2f29a74a7fe9d349501561b50439abfe Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Mon, 1 Feb 2021 19:27:40 +0000
+Subject: [PATCH 08/73] LOCAL: arm64: dts: meson: add rtc/vrtc aliases to Minix
+ NEO U9-H
+
+Add node aliases to prevent meson-vrtc from claiming /dev/rtc0
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ arch/arm64/boot/dts/amlogic/meson-gxm-minix-neo-u9h.dts | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-minix-neo-u9h.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-minix-neo-u9h.dts
+index b8ef3bd8b840..0920e7b096f5 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-gxm-minix-neo-u9h.dts
++++ b/arch/arm64/boot/dts/amlogic/meson-gxm-minix-neo-u9h.dts
+@@ -14,6 +14,11 @@
+ compatible = "minix,neo-u9h", "amlogic,s912", "amlogic,meson-gxm";
+ model = "Minix Neo U9-H";
+
++ aliases {
++ rtc0 = &rtc;
++ rtc1 = &vrtc;
++ };
++
+ leds {
+ compatible = "gpio-leds";
+
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,59 @@
+From 04bdcad098193dda5988bb96bfae7178834b13b0 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 09/73] 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(-)
+
+diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
+index 40751e5aff09..1461463dc320 100644
+--- a/sound/core/pcm_lib.c
++++ b/sound/core/pcm_lib.c
+@@ -2514,7 +2514,10 @@ int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream,
+ 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);
+diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
+index 5679102de91f..aa2ca5078551 100644
+--- a/sound/soc/codecs/hdmi-codec.c
++++ b/sound/soc/codecs/hdmi-codec.c
+@@ -797,7 +797,8 @@ static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd,
+ 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;
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,34 @@
+From 080a637d2fedf1d550f2fcee2da8520cb2456122 Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Mon, 3 Jan 2022 10:44:17 +0000
+Subject: [PATCH 10/73] LOCAL: usb: hub: disable autosuspend for Genesys Logic
+ Hubs
+
+Disable autosuspend in Genesys Logic hubs to allow USB devices on the
+Odroid C2 board to be used. The alternative to this patch is setting
+usbcore.autosuspend=-1 in boot params.
+
+This patch only impacts GXBB devices as GXL/GXM onwards use the newer
+dwc3 core which does not have the problem.
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ drivers/usb/core/hub.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
+index bbab424b0d55..ccfd0b312867 100644
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -5797,7 +5797,7 @@ static const struct usb_device_id hub_id_table[] = {
+ | USB_DEVICE_ID_MATCH_INT_CLASS,
+ .idVendor = USB_VENDOR_GENESYS_LOGIC,
+ .bInterfaceClass = USB_CLASS_HUB,
+- .driver_info = HUB_QUIRK_CHECK_PORT_AUTOSUSPEND},
++ .driver_info = HUB_QUIRK_DISABLE_AUTOSUSPEND},
+ { .match_flags = USB_DEVICE_ID_MATCH_DEV_CLASS,
+ .bDeviceClass = USB_CLASS_HUB},
+ { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,38 @@
+From 31cdc54e582baafbe8e2daf291c35b027081f01d Mon Sep 17 00:00:00 2001
+From: Stefan Agner <stefan@agner.ch>
+Date: Wed, 15 Sep 2021 05:00:45 +0000
+Subject: [PATCH 11/73] LOCAL: 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(-)
+
+diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
+index 1c573e7a60bc..f9188a76500d 100644
+--- a/drivers/of/fdt.c
++++ b/drivers/of/fdt.c
+@@ -481,15 +481,6 @@ static int __init early_init_dt_reserve_memory(phys_addr_t base,
+ 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);
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,57 @@
+From 7712306891a8e02c0253f4b6f68101cf4e567e3a Mon Sep 17 00:00:00 2001
+From: Erico Nunes <nunes.erico@gmail.com>
+Date: Fri, 18 Nov 2022 03:00:39 +0000
+Subject: [PATCH 12/73] FROMGIT: drm/lima: Fix opp clkname setting in case of
+ missing regulator
+
+Commit d8c32d3971e4 ("drm/lima: Migrate to dev_pm_opp_set_config()")
+introduced a regression as it may undo the clk_names setting in case
+the optional regulator is missing. This resulted in test and performance
+regressions with lima.
+
+Restore the old behavior where clk_names is set separately so it is not
+undone in case of a missing optional regulator.
+
+Fixes: d8c32d3971e4 ("drm/lima: Migrate to dev_pm_opp_set_config()")
+Signed-off-by: Erico Nunes <nunes.erico@gmail.com>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+---
+ drivers/gpu/drm/lima/lima_devfreq.c | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/lima/lima_devfreq.c b/drivers/gpu/drm/lima/lima_devfreq.c
+index 011be7ff51e1..bc8fb4e38d0a 100644
+--- a/drivers/gpu/drm/lima/lima_devfreq.c
++++ b/drivers/gpu/drm/lima/lima_devfreq.c
+@@ -112,11 +112,6 @@ int lima_devfreq_init(struct lima_device *ldev)
+ unsigned long cur_freq;
+ int ret;
+ const char *regulator_names[] = { "mali", NULL };
+- const char *clk_names[] = { "core", NULL };
+- struct dev_pm_opp_config config = {
+- .regulator_names = regulator_names,
+- .clk_names = clk_names,
+- };
+
+ if (!device_property_present(dev, "operating-points-v2"))
+ /* Optional, continue without devfreq */
+@@ -124,7 +119,15 @@ int lima_devfreq_init(struct lima_device *ldev)
+
+ spin_lock_init(&ldevfreq->lock);
+
+- ret = devm_pm_opp_set_config(dev, &config);
++ /*
++ * clkname is set separately so it is not affected by the optional
++ * regulator setting which may return error.
++ */
++ ret = devm_pm_opp_set_clkname(dev, "core");
++ if (ret)
++ return ret;
++
++ ret = devm_pm_opp_set_regulators(dev, regulator_names);
+ if (ret) {
+ /* Continue if the optional regulator is missing */
+ if (ret != -ENODEV)
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,30 @@
+From f159c2cb2327d34823fb0731da4f3e7438fad3a9 Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Wed, 6 Jul 2022 09:58:31 +0000
+Subject: [PATCH 13/73] FROMGIT(6.1): dt-bindings: arm: amlogic: add Beelink
+ GT1 Ultimate binding
+
+Add the board binding for the Shenzen AZW (Beelink) GT1 Ultimate
+Android Set-Top Box device.
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+Acked-by: Rob Herring <robh@kernel.org>
+---
+ Documentation/devicetree/bindings/arm/amlogic.yaml | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
+index 61a6cabb375b..3217c069673e 100644
+--- a/Documentation/devicetree/bindings/arm/amlogic.yaml
++++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
+@@ -120,6 +120,7 @@ properties:
+ - enum:
+ - amlogic,q200
+ - amlogic,q201
++ - azw,gt1-ultimate
+ - khadas,vim2
+ - kingnovel,r-box-pro
+ - libretech,aml-s912-pc
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,141 @@
+From 11d8541da45ed52bd6363b8be424289149cb7b7a Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Wed, 6 Jul 2022 09:58:31 +0000
+Subject: [PATCH 14/73] FROMGIT(6.1): arm64: dts: meson: add support for
+ Beelink GT1-Ultimate
+
+The Beelink GT1-Ultimate is based on the Amlogic S912 (Q200)
+reference design with the following specifications:
+
+- 3GB DDR3 RAM
+- 32GB eMMC
+- HDMI 2.1 video
+- S/PDIF optical output
+- 10/100/1000 Ethernet
+- AP6356S Wireless (802.11 a/b/g/n, BT 4.2)
+- 3x USB 2.0 ports
+- IR receiver (internal)
+- 1x micro SD card slot
+- 1x Power LED (white)
+- 1x Reset button (internal)
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
+---
+ arch/arm64/boot/dts/amlogic/Makefile | 1 +
+ .../dts/amlogic/meson-gxm-gt1-ultimate.dts | 91 +++++++++++++++++++
+ 2 files changed, 92 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/amlogic/meson-gxm-gt1-ultimate.dts
+
+diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
+index 8773211df50e..641399fcbdd9 100644
+--- a/arch/arm64/boot/dts/amlogic/Makefile
++++ b/arch/arm64/boot/dts/amlogic/Makefile
+@@ -43,6 +43,7 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-libretech-cc-v2.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-libretech-cc.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-nexbox-a95x.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-p212.dtb
++dtb-$(CONFIG_ARCH_MESON) += meson-gxm-gt1-ultimate.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxm-khadas-vim2.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxm-mecool-kiii-pro.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxm-minix-neo-u9h.dtb
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-gt1-ultimate.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-gt1-ultimate.dts
+new file mode 100644
+index 000000000000..2c267884cc16
+--- /dev/null
++++ b/arch/arm64/boot/dts/amlogic/meson-gxm-gt1-ultimate.dts
+@@ -0,0 +1,91 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++/*
++ * Copyright (c) Christian Hewitt <christianshewitt@gmail.com>
++ */
++
++/dts-v1/;
++
++#include "meson-gxm.dtsi"
++#include "meson-gx-p23x-q20x.dtsi"
++#include <dt-bindings/input/input.h>
++#include <dt-bindings/leds/common.h>
++
++/ {
++ compatible = "azw,gt1-ultimate", "amlogic,s912", "amlogic,meson-gxm";
++ model = "Beelink GT1 Ultimate";
++
++ leds {
++ compatible = "gpio-leds";
++
++ led-white {
++ color = <LED_COLOR_ID_WHITE>;
++ function = LED_FUNCTION_POWER;
++ gpios = <&gpio_ao GPIOAO_9 GPIO_ACTIVE_HIGH>;
++ default-state = "on";
++ panic-indicator;
++ };
++ };
++
++ adc-keys {
++ compatible = "adc-keys";
++ io-channels = <&saradc 0>;
++ io-channel-names = "buttons";
++ keyup-threshold-microvolt = <1710000>;
++
++ button-function {
++ label = "update";
++ linux,code = <KEY_VENDOR>;
++ press-threshold-microvolt = <10000>;
++ };
++ };
++};
++
++ðmac {
++ pinctrl-0 = <ð_pins>;
++ pinctrl-names = "default";
++ phy-handle = <&external_phy>;
++ amlogic,tx-delay-ns = <2>;
++ phy-mode = "rgmii";
++};
++
++&external_mdio {
++ external_phy: ethernet-phy@0 {
++ /* Realtek RTL8211F (0x001cc916) */
++ reg = <0>;
++ max-speed = <1000>;
++
++ reset-assert-us = <10000>;
++ reset-deassert-us = <80000>;
++ reset-gpios = <&gpio GPIOZ_14 GPIO_ACTIVE_LOW>;
++
++ interrupt-parent = <&gpio_intc>;
++ /* MAC_INTR on GPIOZ_15 */
++ interrupts = <25 IRQ_TYPE_LEVEL_LOW>;
++ };
++};
++
++&ir {
++ linux,rc-map-name = "rc-beelink-gs1";
++};
++
++&sd_emmc_a {
++ brcmf: wifi@1 {
++ reg = <1>;
++ compatible = "brcm,bcm4329-fmac";
++ };
++};
++
++&uart_A {
++ status = "okay";
++ pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>;
++ pinctrl-names = "default";
++ uart-has-rtscts;
++
++ bluetooth {
++ compatible = "brcm,bcm43438-bt";
++ shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
++ max-speed = <2000000>;
++ clocks = <&wifi32k>;
++ clock-names = "lpo";
++ };
++};
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,40 @@
+From f1ff5687260210679d811005e7f3fb0ff48a51cc Mon Sep 17 00:00:00 2001
+From: David Heidelberg <david@ixit.cz>
+Date: Sat, 27 Nov 2021 07:23:35 +0000
+Subject: [PATCH 15/73] FROMLIST(v2): arm64: dts: meson: make dts use gpio-fan
+ matrix instead of array
+
+No functional changes.
+
+Adjust to comply with dt-schema requirements
+and make possible to validate values.
+
+Signed-off-by: David Heidelberg <david@ixit.cz>
+Acked-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+---
+ arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts
+index 6d396c1be3d6..9b0c7e9d0620 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts
++++ b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts
+@@ -54,10 +54,11 @@
+ gpios = <&gpio GPIODV_14 GPIO_ACTIVE_HIGH
+ &gpio GPIODV_15 GPIO_ACTIVE_HIGH>;
+ /* Dummy RPM values since fan is optional */
+- gpio-fan,speed-map = <0 0
+- 1 1
+- 2 2
+- 3 3>;
++ gpio-fan,speed-map =
++ <0 0>,
++ <1 1>,
++ <2 2>,
++ <3 3>;
+ #cooling-cells = <2>;
+ };
+
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,36 @@
+From fe266042ccee82d0997fdc437572de68ff9a1a76 Mon Sep 17 00:00:00 2001
+From: Sergey Shtylyov <s.shtylyov@omp.ru>
+Date: Fri, 24 Dec 2021 06:09:57 +0000
+Subject: [PATCH 16/73] FROMLIST(v1): mmc: meson-gx: fix deferred probing
+
+The driver overrides the error codes and IRQ0 returned by platform_get_irq()
+to -EINVAL, so if it returns -EPROBE_DEFER, the driver will fail the probe
+permanently instead of the deferred probing. Switch to propagating the error
+codes upstream. IRQ0 is no longer returned by platform_get_irq(), so we now
+can safely ignore it...
+
+Fixes: cbcaac6d7dd2 ("mmc: meson-gx-mmc: Fix platform_get_irq's error checking")
+Signed-off-by: Sergey Shtylyov <s.shtylyov@omp.ru>
+Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+---
+ drivers/mmc/host/meson-gx-mmc.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c
+index fc462995cf94..a2aacbffc3bf 100644
+--- a/drivers/mmc/host/meson-gx-mmc.c
++++ b/drivers/mmc/host/meson-gx-mmc.c
+@@ -1185,8 +1185,8 @@ static int meson_mmc_probe(struct platform_device *pdev)
+ }
+
+ host->irq = platform_get_irq(pdev, 0);
+- if (host->irq <= 0) {
+- ret = -EINVAL;
++ if (host->irq < 0) {
++ ret = host->irq;
+ goto free_host;
+ }
+
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,34 @@
+From d04e53e0b5cc15aeee4cd078706226ea80d47dee Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Andreas=20F=C3=A4rber?= <afaerber@suse.de>
+Date: Sun, 20 Feb 2022 08:23:12 +0000
+Subject: [PATCH 17/73] FROMLIST(v5): dt-bindings: vendor-prefixes: Add Titan
+ Micro Electronics
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Assign vendor prefix "titanmec", matching their domain name.
+
+Acked-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Andreas Färber <afaerber@suse.de>
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+---
+ Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
+index 2f0151e9f6be..7163901e5976 100644
+--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
++++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
+@@ -1291,6 +1291,8 @@ patternProperties:
+ description: Texas Instruments
+ "^tianma,.*":
+ description: Tianma Micro-electronics Co., Ltd.
++ "^titanmec,.*":
++ description: Shenzhen Titan Micro Electronics Co., Ltd.
+ "^tlm,.*":
+ description: Trusted Logic Mobility
+ "^tmt,.*":
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,114 @@
+From 1bc9224b52be0df338c4e63e122460df0f651d96 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Sun, 20 Feb 2022 08:24:47 +0000
+Subject: [PATCH 18/73] FROMLIST(v5): dt-bindings: auxdisplay: Add Titan Micro
+ Electronics TM1628
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add a YAML schema binding for TM1628 auxdisplay
+(7/11-segment LED) controller.
+
+This patch is partially based on previous RFC work from
+Andreas Färber <afaerber@suse.de>.
+
+Co-developed-by: Andreas Färber <afaerber@suse.de>
+Signed-off-by: Andreas Färber <afaerber@suse.de>
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+---
+ .../bindings/auxdisplay/titanmec,tm1628.yaml | 82 +++++++++++++++++++
+ 1 file changed, 82 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/auxdisplay/titanmec,tm1628.yaml
+
+diff --git a/Documentation/devicetree/bindings/auxdisplay/titanmec,tm1628.yaml b/Documentation/devicetree/bindings/auxdisplay/titanmec,tm1628.yaml
+new file mode 100644
+index 000000000000..d9cbbc950aab
+--- /dev/null
++++ b/Documentation/devicetree/bindings/auxdisplay/titanmec,tm1628.yaml
+@@ -0,0 +1,82 @@
++# SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/leds/titanmec,tm1628.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Titan Micro Electronics TM1628 LED controller
++
++properties:
++ compatible:
++ enum:
++ - titanmec,tm1628
++
++ reg:
++ maxItems: 1
++
++ grid:
++ description:
++ Mapping of display digit position to grid number.
++ This implicitly defines the display size.
++ $ref: /schemas/types.yaml#/definitions/uint8-array
++ minItems: 1
++ maxItems: 7
++
++ segment-mapping:
++ description:
++ Mapping of 7 segment display segments A-G to bit numbers 1-12.
++ $ref: /schemas/types.yaml#/definitions/uint8-array
++ minItems: 7
++ maxItems: 7
++
++ "#address-cells":
++ const: 2
++
++ "#size-cells":
++ const: 0
++
++required:
++ - compatible
++ - reg
++
++patternProperties:
++ "^.*@[1-7],([1-9]|1[0-6])$":
++ type: object
++ description: |
++ Properties for a single LED.
++
++ properties:
++ reg:
++ description: |
++ 1-based grid number, followed by 1-based segment bit number.
++ maxItems: 1
++
++ required:
++ - reg
++
++examples:
++ - |
++ #include <dt-bindings/leds/common.h>
++
++ spi {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ led-controller@0 {
++ compatible = "titanmec,tm1628";
++ reg = <0>;
++ spi-3-wire;
++ spi-lsb-first;
++ spi-max-frequency = <500000>;
++ grid = /bits/ 8 <4 3 2 1>;
++ segment-mapping = /bits/ 8 <4 5 6 1 2 3 7>;
++ #address-cells = <2>;
++ #size-cells = <0>;
++
++ alarmn@5,4 {
++ reg = <5 4>;
++ function = LED_FUNCTION_ALARM;
++ };
++ };
++ };
++...
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,31 @@
+From 12d50549e630b703799379595f49c363ac6b8308 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Sun, 20 Feb 2022 08:26:27 +0000
+Subject: [PATCH 19/73] FROMLIST(v5): docs: ABI: document tm1628 attribute
+ display-text
+
+Document the attribute for reading / writing the text to be displayed on
+the 7 segment display.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+---
+ Documentation/ABI/testing/sysfs-devices-auxdisplay-tm1628 | 7 +++++++
+ 1 file changed, 7 insertions(+)
+ create mode 100644 Documentation/ABI/testing/sysfs-devices-auxdisplay-tm1628
+
+diff --git a/Documentation/ABI/testing/sysfs-devices-auxdisplay-tm1628 b/Documentation/ABI/testing/sysfs-devices-auxdisplay-tm1628
+new file mode 100644
+index 000000000000..382757e721af
+--- /dev/null
++++ b/Documentation/ABI/testing/sysfs-devices-auxdisplay-tm1628
+@@ -0,0 +1,7 @@
++What: /sys/devices/.../display-text
++Date: February 2022
++Contact: Heiner Kallweit <hkallweit1@gmail.com>
++Description:
++ The text to be displayed on the 7 segment display.
++ Any printable character is allowed as input, but some
++ can not be displayed in a readable way with 7 segments.
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,461 @@
+From 90b0ef46ad6cc8ea91a75d59561f2ce837319c83 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Mon, 4 Apr 2022 18:51:20 +0000
+Subject: [PATCH 20/73] FROMLIST(v5): auxdisplay: add support for Titanmec
+ TM1628 7 segment display controller
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This patch adds support for the Titanmec TM1628 7 segment display
+controller. It's based on previous RFC work from Andreas Färber.
+The RFC version placed the driver in the LED subsystem, but this was
+NAK'ed by the LED maintainer. Therefore I moved the driver to
+/drivers/auxdisplay what seems most reasonable to me.
+
+Further changes to the RFC version:
+- Driver can be built also w/o LED class support, for displays that
+ don't have any symbols to be exposed as LED's.
+- Simplified the code and rewrote a lot of it.
+- Driver is now kind of a MVP, but functionality should be sufficient
+ for most use cases.
+- Use the existing 7 segment support in uapi/linux/map_to_7segment.h
+ as suggested by Geert Uytterhoeven.
+
+Note: There's a number of chips from other manufacturers that are
+ almost identical, e.g. FD628, SM1628. Only difference I saw so
+ far is that they partially support other display modes.
+ TM1628: 6x12, 7x11
+ SM1628C: 4x13, 5x12, 6x11, 7x10
+ For typical displays on devices using these chips this
+ difference shouldn't matter.
+
+Successfully tested on a TX3 Mini TV box that has an SM1628C and a
+display with 4 digits and 7 symbols.
+
+Co-developed-by: Andreas Färber <afaerber@suse.de>
+Signed-off-by: Andreas Färber <afaerber@suse.de>
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+---
+ drivers/auxdisplay/Kconfig | 11 ++
+ drivers/auxdisplay/Makefile | 1 +
+ drivers/auxdisplay/tm1628.c | 376 ++++++++++++++++++++++++++++++++++++
+ 3 files changed, 388 insertions(+)
+ create mode 100644 drivers/auxdisplay/tm1628.c
+
+diff --git a/drivers/auxdisplay/Kconfig b/drivers/auxdisplay/Kconfig
+index 64012cda4d12..2764afc5c5d9 100644
+--- a/drivers/auxdisplay/Kconfig
++++ b/drivers/auxdisplay/Kconfig
+@@ -203,6 +203,17 @@ config ARM_CHARLCD
+ line and the Linux version on the second line, but that's
+ still useful.
+
++config TM1628
++ tristate "TM1628 driver for LED 7/11 segment displays"
++ depends on SPI
++ depends on OF || COMPILE_TEST
++ help
++ Say Y to enable support for Titan Micro Electronics TM1628
++ LED controller.
++
++ It's a 3-wire SPI device controlling a two-dimensional grid of
++ LEDs. Dimming is applied to all outputs through an internal PWM.
++
+ menuconfig PARPORT_PANEL
+ tristate "Parallel port LCD/Keypad Panel support"
+ depends on PARPORT
+diff --git a/drivers/auxdisplay/Makefile b/drivers/auxdisplay/Makefile
+index 6968ed4d3f0a..7728e17e1c5a 100644
+--- a/drivers/auxdisplay/Makefile
++++ b/drivers/auxdisplay/Makefile
+@@ -14,3 +14,4 @@ obj-$(CONFIG_HT16K33) += ht16k33.o
+ obj-$(CONFIG_PARPORT_PANEL) += panel.o
+ obj-$(CONFIG_LCD2S) += lcd2s.o
+ obj-$(CONFIG_LINEDISP) += line-display.o
++obj-$(CONFIG_TM1628) += tm1628.o
+diff --git a/drivers/auxdisplay/tm1628.c b/drivers/auxdisplay/tm1628.c
+new file mode 100644
+index 000000000000..4d99a7aa077b
+--- /dev/null
++++ b/drivers/auxdisplay/tm1628.c
+@@ -0,0 +1,376 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++/*
++ * Titan Micro Electronics TM1628 LED controller
++ *
++ * Copyright (c) 2019 Andreas Färber
++ * Copyright (c) 2022 Heiner Kallweit
++ */
++
++#include <linux/ctype.h>
++#include <linux/delay.h>
++#include <linux/leds.h>
++#include <linux/module.h>
++#include <linux/property.h>
++#include <linux/spi/spi.h>
++#include <uapi/linux/map_to_7segment.h>
++
++#define TM1628_CMD_DISPLAY_MODE (0 << 6)
++#define TM1628_DISPLAY_MODE_6_12 0x02
++#define TM1628_DISPLAY_MODE_7_11 0x03
++
++#define TM1628_CMD_DATA (1 << 6)
++#define TM1628_DATA_TEST_MODE BIT(3)
++#define TM1628_DATA_FIXED_ADDR BIT(2)
++#define TM1628_DATA_WRITE_DATA 0x00
++#define TM1628_DATA_READ_DATA 0x02
++
++#define TM1628_CMD_DISPLAY_CTRL (2 << 6)
++#define TM1628_DISPLAY_CTRL_DISPLAY_ON BIT(3)
++
++#define TM1628_CMD_SET_ADDRESS (3 << 6)
++
++#define TM1628_BRIGHTNESS_MAX 7
++#define NUM_LED_SEGS 7
++
++/* Physical limits, depending on the mode the chip may support less */
++#define MAX_GRID_SIZE 7
++#define MAX_SEGMENT_NUM 16
++
++struct tm1628_led {
++ struct led_classdev leddev;
++ struct tm1628 *ctrl;
++ u32 grid;
++ u32 seg;
++};
++
++struct tm1628 {
++ struct spi_device *spi;
++ __le16 data[MAX_GRID_SIZE];
++ struct mutex disp_lock;
++ char text[MAX_GRID_SIZE + 1];
++ u8 segment_mapping[NUM_LED_SEGS];
++ u8 grid[MAX_GRID_SIZE];
++ int grid_size;
++ struct tm1628_led leds[];
++};
++
++/* Command 1: Display Mode Setting */
++static int tm1628_set_display_mode(struct spi_device *spi, u8 grid_mode)
++{
++ const u8 cmd = TM1628_CMD_DISPLAY_MODE | grid_mode;
++
++ return spi_write(spi, &cmd, 1);
++}
++
++/* Command 3: Address Setting */
++static int tm1628_set_address(struct spi_device *spi, u8 offset)
++{
++ const u8 cmd = TM1628_CMD_SET_ADDRESS | (offset * sizeof(__le16));
++
++ return spi_write(spi, &cmd, 1);
++}
++
++/* Command 2: Data Setting */
++static int tm1628_write_data(struct spi_device *spi, unsigned int offset,
++ unsigned int len)
++{
++ struct tm1628 *s = spi_get_drvdata(spi);
++ const u8 cmd = TM1628_CMD_DATA | TM1628_DATA_WRITE_DATA;
++ struct spi_transfer xfers[] = {
++ {
++ .tx_buf = &cmd,
++ .len = 1,
++ },
++ {
++ .tx_buf = (__force void *)(s->data + offset),
++ .len = len * sizeof(__le16),
++ },
++ };
++
++ if (offset + len > MAX_GRID_SIZE) {
++ dev_err(&spi->dev, "Invalid data address offset %u len %u\n",
++ offset, len);
++ return -EINVAL;
++ }
++
++ tm1628_set_address(spi, offset);
++
++ return spi_sync_transfer(spi, xfers, ARRAY_SIZE(xfers));
++}
++
++/* Command 4: Display Control */
++static int tm1628_set_display_ctrl(struct spi_device *spi, bool on)
++{
++ u8 cmd = TM1628_CMD_DISPLAY_CTRL | TM1628_BRIGHTNESS_MAX;
++
++ if (on)
++ cmd |= TM1628_DISPLAY_CTRL_DISPLAY_ON;
++
++ return spi_write(spi, &cmd, 1);
++}
++
++static int tm1628_show_text(struct tm1628 *s)
++{
++ static SEG7_CONVERSION_MAP(map_seg7, MAP_ASCII7SEG_ALPHANUM);
++ int msg_len, i, ret;
++
++ msg_len = strlen(s->text);
++
++ mutex_lock(&s->disp_lock);
++
++ for (i = 0; i < s->grid_size; i++) {
++ int pos = s->grid[i] - 1;
++ int j, char7_raw, char7;
++
++ if (i >= msg_len) {
++ s->data[pos] = 0;
++ continue;
++ }
++
++ char7_raw = map_to_seg7(&map_seg7, s->text[i]);
++
++ for (j = 0, char7 = 0; j < NUM_LED_SEGS; j++) {
++ if (char7_raw & BIT(j))
++ char7 |= BIT(s->segment_mapping[j] - 1);
++ }
++
++ s->data[pos] = cpu_to_le16(char7);
++ }
++
++ ret = tm1628_write_data(s->spi, 0, s->grid_size);
++
++ mutex_unlock(&s->disp_lock);
++
++ return ret;
++}
++
++static int tm1628_led_set_brightness(struct led_classdev *led_cdev,
++ enum led_brightness brightness)
++{
++ struct tm1628_led *led = container_of(led_cdev, struct tm1628_led, leddev);
++ struct tm1628 *s = led->ctrl;
++ int ret, offset = led->grid - 1;
++ __le16 bit = cpu_to_le16(BIT(led->seg - 1));
++
++ mutex_lock(&s->disp_lock);
++
++ if (brightness == LED_OFF)
++ s->data[offset] &= ~bit;
++ else
++ s->data[offset] |= bit;
++
++ ret = tm1628_write_data(s->spi, offset, 1);
++
++ mutex_unlock(&s->disp_lock);
++
++ return ret;
++}
++
++static enum led_brightness tm1628_led_get_brightness(struct led_classdev *led_cdev)
++{
++ struct tm1628_led *led = container_of(led_cdev, struct tm1628_led, leddev);
++ struct tm1628 *s = led->ctrl;
++ int offset = led->grid - 1;
++ __le16 bit = cpu_to_le16(BIT(led->seg - 1));
++ bool on;
++
++ mutex_lock(&s->disp_lock);
++ on = s->data[offset] & bit;
++ mutex_unlock(&s->disp_lock);
++
++ return on ? LED_ON : LED_OFF;
++}
++
++static int tm1628_register_led(struct tm1628 *s, struct fwnode_handle *node,
++ u32 grid, u32 seg, struct tm1628_led *led)
++{
++ struct device *dev = &s->spi->dev;
++ struct led_init_data init_data = { .fwnode = node };
++
++ led->ctrl = s;
++ led->grid = grid;
++ led->seg = seg;
++ led->leddev.max_brightness = LED_ON;
++ led->leddev.brightness_set_blocking = tm1628_led_set_brightness;
++ led->leddev.brightness_get = tm1628_led_get_brightness;
++
++ return devm_led_classdev_register_ext(dev, &led->leddev, &init_data);
++}
++
++static ssize_t display_text_show(struct device *dev, struct device_attribute *attr,
++ char *buf)
++{
++ struct tm1628 *s = dev_get_drvdata(dev);
++
++ return sysfs_emit(buf, "%s\n", s->text);
++}
++
++static ssize_t display_text_store(struct device *dev, struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct tm1628 *s = dev_get_drvdata(dev);
++ int ret, i;
++
++ for (i = 0; i < count && i < s->grid_size && isprint(buf[i]); i++)
++ s->text[i] = buf[i];
++
++ s->text[i] = '\0';
++
++ ret = tm1628_show_text(s);
++ if (ret < 0)
++ return ret;
++
++ return count;
++}
++
++static const DEVICE_ATTR_RW(display_text);
++
++static int tm1628_spi_probe(struct spi_device *spi)
++{
++ struct fwnode_handle *child;
++ unsigned int num_leds;
++ struct tm1628 *s;
++ int ret, i;
++
++ num_leds = device_get_child_node_count(&spi->dev);
++
++ s = devm_kzalloc(&spi->dev, struct_size(s, leds, num_leds), GFP_KERNEL);
++ if (!s)
++ return -ENOMEM;
++
++ s->spi = spi;
++ spi_set_drvdata(spi, s);
++
++ mutex_init(&s->disp_lock);
++
++ /* According to TM1628 datasheet */
++ msleep(200);
++
++ /* Clear screen */
++ ret = tm1628_write_data(spi, 0, MAX_GRID_SIZE);
++ if (ret)
++ return ret;
++
++ /* For now we support 6x12 mode only. This should be sufficient for most use cases */
++ ret = tm1628_set_display_mode(spi, TM1628_DISPLAY_MODE_6_12);
++ if (ret)
++ return ret;
++
++ ret = tm1628_set_display_ctrl(spi, true);
++ if (ret)
++ return ret;
++
++ num_leds = 0;
++
++ if (!IS_REACHABLE(CONFIG_LEDS_CLASS))
++ goto no_leds;
++
++ device_for_each_child_node(&spi->dev, child) {
++ u32 reg[2];
++
++ ret = fwnode_property_read_u32_array(child, "reg", reg, 2);
++ if (ret) {
++ dev_err(&spi->dev, "Reading %s reg property failed (%d)\n",
++ fwnode_get_name(child), ret);
++ continue;
++ }
++
++ if (reg[0] == 0 || reg[0] > MAX_GRID_SIZE) {
++ dev_err(&spi->dev, "Invalid grid %u at %s\n",
++ reg[0], fwnode_get_name(child));
++ continue;
++ }
++
++ if (reg[1] == 0 || reg[1] > MAX_SEGMENT_NUM) {
++ dev_err(&spi->dev, "Invalid segment %u at %s\n",
++ reg[1], fwnode_get_name(child));
++ continue;
++ }
++
++ ret = tm1628_register_led(s, child, reg[0], reg[1], s->leds + num_leds);
++ if (ret) {
++ dev_err(&spi->dev, "Failed to register LED %s (%d)\n",
++ fwnode_get_name(child), ret);
++ continue;
++ }
++ num_leds++;
++ }
++
++no_leds:
++ ret = device_property_count_u8(&spi->dev, "titanmec,grid");
++ if (ret < 1 || ret > MAX_GRID_SIZE) {
++ dev_err(&spi->dev, "Invalid display length (%d)\n", ret);
++ return -EINVAL;
++ }
++
++ s->grid_size = ret;
++
++ ret = device_property_read_u8_array(&spi->dev, "titanmec,grid", s->grid, s->grid_size);
++ if (ret < 0)
++ return ret;
++
++ for (i = 0; i < s->grid_size; i++) {
++ if (s->grid[i] < 1 || s->grid[i] > s->grid_size)
++ return -EINVAL;
++ }
++
++ ret = device_property_read_u8_array(&spi->dev, "titanmec,segment-mapping",
++ s->segment_mapping, NUM_LED_SEGS);
++ if (ret < 0)
++ return ret;
++
++ for (i = 0; i < NUM_LED_SEGS; i++) {
++ if (s->segment_mapping[i] < 1 || s->segment_mapping[i] > MAX_SEGMENT_NUM)
++ return -EINVAL;
++ }
++
++ ret = device_create_file(&spi->dev, &dev_attr_display_text);
++ if (ret)
++ return ret;
++
++ dev_info(&spi->dev, "Configured display with %u digits and %u symbols\n",
++ s->grid_size, num_leds);
++
++ return 0;
++}
++
++static void tm1628_spi_remove(struct spi_device *spi)
++{
++ device_remove_file(&spi->dev, &dev_attr_display_text);
++ tm1628_set_display_ctrl(spi, false);
++}
++
++static void tm1628_spi_shutdown(struct spi_device *spi)
++{
++ tm1628_set_display_ctrl(spi, false);
++}
++
++static const struct of_device_id tm1628_spi_of_matches[] = {
++ { .compatible = "titanmec,tm1628" },
++ {}
++};
++MODULE_DEVICE_TABLE(of, tm1628_spi_of_matches);
++
++static const struct spi_device_id tm1628_spi_id_table[] = {
++ { "tm1628" },
++ {},
++};
++MODULE_DEVICE_TABLE(spi, tm1628_spi_id_table);
++
++static struct spi_driver tm1628_spi_driver = {
++ .probe = tm1628_spi_probe,
++ .remove = tm1628_spi_remove,
++ .shutdown = tm1628_spi_shutdown,
++ .id_table = tm1628_spi_id_table,
++
++ .driver = {
++ .name = "tm1628",
++ .of_match_table = tm1628_spi_of_matches,
++ },
++};
++module_spi_driver(tm1628_spi_driver);
++
++MODULE_DESCRIPTION("TM1628 LED controller driver");
++MODULE_AUTHOR("Andreas Färber <afaerber@suse.de>");
++MODULE_AUTHOR("Heiner Kallweit <hkallweit1@gmail.com>");
++MODULE_LICENSE("GPL");
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,93 @@
+From 42aab91da4a46c2be7e2f0f8ef578621bccc0665 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Mon, 4 Apr 2022 18:52:34 +0000
+Subject: [PATCH 21/73] FROMLIST(v5): arm64: dts: meson-gxl-s905w-tx3-mini: add
+ support for the 7 segment display
+
+This patch adds support for the 7 segment display of the device.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+---
+ .../dts/amlogic/meson-gxl-s905w-tx3-mini.dts | 59 +++++++++++++++++++
+ 1 file changed, 59 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905w-tx3-mini.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905w-tx3-mini.dts
+index 6705c2082a78..ae0d8d7b1e19 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905w-tx3-mini.dts
++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905w-tx3-mini.dts
+@@ -10,6 +10,7 @@
+
+ #include "meson-gxl-s905x.dtsi"
+ #include "meson-gx-p23x-q20x.dtsi"
++#include <dt-bindings/leds/common.h>
+
+ / {
+ compatible = "oranth,tx3-mini", "amlogic,s905w", "amlogic,meson-gxl";
+@@ -19,6 +20,64 @@
+ device_type = "memory";
+ reg = <0x0 0x0 0x0 0x40000000>; /* 1 GiB or 2 GiB */
+ };
++
++ spi {
++ compatible = "spi-gpio";
++ sck-gpios = <&gpio GPIODV_27 GPIO_ACTIVE_HIGH>;
++ mosi-gpios = <&gpio GPIODV_26 GPIO_ACTIVE_HIGH>;
++ cs-gpios = <&gpio_ao GPIOAO_4 GPIO_ACTIVE_LOW>;
++ num-chipselects = <1>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ tm1628: led-controller@0 {
++ compatible = "titanmec,tm1628";
++ reg = <0>;
++ spi-3wire;
++ spi-lsb-first;
++ spi-rx-delay-us = <1>;
++ spi-max-frequency = <500000>;
++ #address-cells = <2>;
++ #size-cells = <0>;
++
++ titanmec,segment-mapping = /bits/ 8 <4 5 6 1 2 3 7>;
++ titanmec,grid = /bits/ 8 <4 3 2 1>;
++
++ alarm@5,1 {
++ reg = <5 1>;
++ function = LED_FUNCTION_ALARM;
++ };
++
++ usb@5,2 {
++ reg = <5 2>;
++ function = LED_FUNCTION_USB;
++ };
++ play@5,3 {
++ reg = <5 3>;
++ function = "play";
++ };
++
++ pause@5,4 {
++ reg = <5 4>;
++ function = "pause";
++ };
++
++ colon@5,5 {
++ reg = <5 5>;
++ function = "colon";
++ };
++
++ lan@5,6 {
++ reg = <5 6>;
++ function = LED_FUNCTION_LAN;
++ };
++
++ wlan@5,7 {
++ reg = <5 7>;
++ function = LED_FUNCTION_WLAN;
++ };
++ };
++ };
+ };
+
+ &ir {
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,32 @@
+From b302175edf75e8729fe5a5b6dae4bed90525ab8d Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Mon, 4 Apr 2022 18:53:32 +0000
+Subject: [PATCH 22/73] FROMLIST(v5): MAINTAINERS: Add entry for tm1628
+ auxdisplay driver
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+---
+ MAINTAINERS | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/MAINTAINERS b/MAINTAINERS
+index 72b9654f764c..8889d9dbd71a 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -20481,6 +20481,13 @@ W: http://sourceforge.net/projects/tlan/
+ F: Documentation/networking/device_drivers/ethernet/ti/tlan.rst
+ F: drivers/net/ethernet/ti/tlan.*
+
++TM1628 LED CONTROLLER DRIVER
++M: Heiner Kallweit <hkallweit1@gmail.com>
++S: Maintained
++F: Documentation/devicetree/bindings/auxdisplay/titanmec,tm1628.yaml
++F: Documentation/ABI/testing/sysfs-devices-auxdisplay-tm1628
++F: drivers/auxdisplay/tm1628.c
++
+ TM6000 VIDEO4LINUX DRIVER
+ M: Mauro Carvalho Chehab <mchehab@kernel.org>
+ L: linux-media@vger.kernel.org
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,49 @@
+From 0ae242ebcee68a9b02f466b00ff46944390d80cd Mon Sep 17 00:00:00 2001
+From: Guillaume BRUN <the.cheaterman@gmail.com>
+Date: Thu, 13 Oct 2022 13:21:53 +0000
+Subject: [PATCH 23/73] FROMLIST(v1): drm: bridge: dw_hdmi: fix preference of
+ RGB modes over YUV420
+
+Cheap monitors sometimes advertise YUV modes they don't really have
+(HDMI specification mandates YUV support so even monitors without actual
+support will often wrongfully advertise it) which results in YUV matches
+and user forum complaints of a red tint to light colour display areas in
+common desktop environments.
+
+Moving the default RGB fall-back before YUV selection results in RGB
+mode matching in most cases, reducing complaints.
+
+Fixes: 6c3c719936da ("drm/bridge: synopsys: dw-hdmi: add bus format negociation")
+Signed-off-by: Guillaume BRUN <the.cheaterman@gmail.com>
+Tested-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+index 40d8ca37f5bc..aa51c61a78c7 100644
+--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+@@ -2720,6 +2720,9 @@ static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
+ * if supported. In any case the default RGB888 format is added
+ */
+
++ /* Default 8bit RGB fallback */
++ output_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24;
++
+ if (max_bpc >= 16 && info->bpc == 16) {
+ if (info->color_formats & DRM_COLOR_FORMAT_YCBCR444)
+ output_fmts[i++] = MEDIA_BUS_FMT_YUV16_1X48;
+@@ -2753,9 +2756,6 @@ static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
+ if (info->color_formats & DRM_COLOR_FORMAT_YCBCR444)
+ output_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24;
+
+- /* Default 8bit RGB fallback */
+- output_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24;
+-
+ *num_output_fmts = i;
+
+ return output_fmts;
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,202 @@
+From 5c71bbe15728d90b905b1539a394a6c78aa3339f Mon Sep 17 00:00:00 2001
+From: Jonas Karlman <jonas@kwiboo.se>
+Date: Sun, 23 Dec 2018 02:24:38 +0100
+Subject: [PATCH 24/73] WIP: ASoC: hdmi-codec: reorder channel allocation list
+
+Wrong channel allocation is selected by hdmi_codec_get_ch_alloc_table_idx().
+
+E.g when ELD reports FL|FR|LFE|FC|RL|RR or FL|FR|LFE|FC|RL|RR|RC|RLC|RRC
+
+ca_id 0x01 with speaker mask FL|FR|LFE gets selected instead of
+ca_id 0x03 with speaker mask FL|FR|LFE|FC for 4 channels
+
+and
+
+ca_id 0x04 with speaker mask FL|FR|RC gets selected instead of
+ca_id 0x0b with speaker mask FL|FR|LFE|FC|RL|RR for 6 channels
+
+Fix this by reorder the channel allocation list with
+most specific speaker mask at the top.
+
+Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
+---
+ sound/soc/codecs/hdmi-codec.c | 140 +++++++++++++++++++---------------
+ 1 file changed, 77 insertions(+), 63 deletions(-)
+
+diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
+index aa2ca5078551..bed6dba14243 100644
+--- a/sound/soc/codecs/hdmi-codec.c
++++ b/sound/soc/codecs/hdmi-codec.c
+@@ -188,84 +188,97 @@ static const struct snd_pcm_chmap_elem hdmi_codec_8ch_chmaps[] = {
+ /*
+ * hdmi_codec_channel_alloc: speaker configuration available for CEA
+ *
+- * This is an ordered list that must match with hdmi_codec_8ch_chmaps struct
++ * This is an ordered list where ca_id must exist in hdmi_codec_8ch_chmaps
+ * The preceding ones have better chances to be selected by
+ * hdmi_codec_get_ch_alloc_table_idx().
+ */
+ static const struct hdmi_codec_cea_spk_alloc hdmi_codec_channel_alloc[] = {
+ { .ca_id = 0x00, .n_ch = 2,
+- .mask = FL | FR},
+- /* 2.1 */
+- { .ca_id = 0x01, .n_ch = 4,
+- .mask = FL | FR | LFE},
+- /* Dolby Surround */
++ .mask = FL | FR },
++ { .ca_id = 0x03, .n_ch = 4,
++ .mask = FL | FR | LFE | FC },
+ { .ca_id = 0x02, .n_ch = 4,
+ .mask = FL | FR | FC },
+- /* surround51 */
++ { .ca_id = 0x01, .n_ch = 4,
++ .mask = FL | FR | LFE },
+ { .ca_id = 0x0b, .n_ch = 6,
+- .mask = FL | FR | LFE | FC | RL | RR},
+- /* surround40 */
+- { .ca_id = 0x08, .n_ch = 6,
+- .mask = FL | FR | RL | RR },
+- /* surround41 */
+- { .ca_id = 0x09, .n_ch = 6,
+- .mask = FL | FR | LFE | RL | RR },
+- /* surround50 */
++ .mask = FL | FR | LFE | FC | RL | RR },
+ { .ca_id = 0x0a, .n_ch = 6,
+ .mask = FL | FR | FC | RL | RR },
+- /* 6.1 */
+- { .ca_id = 0x0f, .n_ch = 8,
+- .mask = FL | FR | LFE | FC | RL | RR | RC },
+- /* surround71 */
++ { .ca_id = 0x09, .n_ch = 6,
++ .mask = FL | FR | LFE | RL | RR },
++ { .ca_id = 0x08, .n_ch = 6,
++ .mask = FL | FR | RL | RR },
++ { .ca_id = 0x07, .n_ch = 6,
++ .mask = FL | FR | LFE | FC | RC },
++ { .ca_id = 0x06, .n_ch = 6,
++ .mask = FL | FR | FC | RC },
++ { .ca_id = 0x05, .n_ch = 6,
++ .mask = FL | FR | LFE | RC },
++ { .ca_id = 0x04, .n_ch = 6,
++ .mask = FL | FR | RC },
+ { .ca_id = 0x13, .n_ch = 8,
+ .mask = FL | FR | LFE | FC | RL | RR | RLC | RRC },
+- /* others */
+- { .ca_id = 0x03, .n_ch = 8,
+- .mask = FL | FR | LFE | FC },
+- { .ca_id = 0x04, .n_ch = 8,
+- .mask = FL | FR | RC},
+- { .ca_id = 0x05, .n_ch = 8,
+- .mask = FL | FR | LFE | RC },
+- { .ca_id = 0x06, .n_ch = 8,
+- .mask = FL | FR | FC | RC },
+- { .ca_id = 0x07, .n_ch = 8,
+- .mask = FL | FR | LFE | FC | RC },
+- { .ca_id = 0x0c, .n_ch = 8,
+- .mask = FL | FR | RC | RL | RR },
+- { .ca_id = 0x0d, .n_ch = 8,
+- .mask = FL | FR | LFE | RL | RR | RC },
+- { .ca_id = 0x0e, .n_ch = 8,
+- .mask = FL | FR | FC | RL | RR | RC },
+- { .ca_id = 0x10, .n_ch = 8,
+- .mask = FL | FR | RL | RR | RLC | RRC },
+- { .ca_id = 0x11, .n_ch = 8,
+- .mask = FL | FR | LFE | RL | RR | RLC | RRC },
++ { .ca_id = 0x1f, .n_ch = 8,
++ .mask = FL | FR | LFE | FC | RL | RR | FLC | FRC },
+ { .ca_id = 0x12, .n_ch = 8,
+ .mask = FL | FR | FC | RL | RR | RLC | RRC },
+- { .ca_id = 0x14, .n_ch = 8,
+- .mask = FL | FR | FLC | FRC },
+- { .ca_id = 0x15, .n_ch = 8,
+- .mask = FL | FR | LFE | FLC | FRC },
+- { .ca_id = 0x16, .n_ch = 8,
+- .mask = FL | FR | FC | FLC | FRC },
+- { .ca_id = 0x17, .n_ch = 8,
+- .mask = FL | FR | LFE | FC | FLC | FRC },
+- { .ca_id = 0x18, .n_ch = 8,
+- .mask = FL | FR | RC | FLC | FRC },
+- { .ca_id = 0x19, .n_ch = 8,
+- .mask = FL | FR | LFE | RC | FLC | FRC },
+- { .ca_id = 0x1a, .n_ch = 8,
+- .mask = FL | FR | RC | FC | FLC | FRC },
+- { .ca_id = 0x1b, .n_ch = 8,
+- .mask = FL | FR | LFE | RC | FC | FLC | FRC },
+- { .ca_id = 0x1c, .n_ch = 8,
+- .mask = FL | FR | RL | RR | FLC | FRC },
+- { .ca_id = 0x1d, .n_ch = 8,
+- .mask = FL | FR | LFE | RL | RR | FLC | FRC },
+ { .ca_id = 0x1e, .n_ch = 8,
+ .mask = FL | FR | FC | RL | RR | FLC | FRC },
+- { .ca_id = 0x1f, .n_ch = 8,
+- .mask = FL | FR | LFE | FC | RL | RR | FLC | FRC },
++ { .ca_id = 0x11, .n_ch = 8,
++ .mask = FL | FR | LFE | RL | RR | RLC | RRC },
++ { .ca_id = 0x1d, .n_ch = 8,
++ .mask = FL | FR | LFE | RL | RR | FLC | FRC },
++ { .ca_id = 0x10, .n_ch = 8,
++ .mask = FL | FR | RL | RR | RLC | RRC },
++ { .ca_id = 0x1c, .n_ch = 8,
++ .mask = FL | FR | RL | RR | FLC | FRC },
++ { .ca_id = 0x0f, .n_ch = 8,
++ .mask = FL | FR | LFE | FC | RL | RR | RC },
++ { .ca_id = 0x1b, .n_ch = 8,
++ .mask = FL | FR | LFE | RC | FC | FLC | FRC },
++ { .ca_id = 0x0e, .n_ch = 8,
++ .mask = FL | FR | FC | RL | RR | RC },
++ { .ca_id = 0x1a, .n_ch = 8,
++ .mask = FL | FR | RC | FC | FLC | FRC },
++ { .ca_id = 0x0d, .n_ch = 8,
++ .mask = FL | FR | LFE | RL | RR | RC },
++ { .ca_id = 0x19, .n_ch = 8,
++ .mask = FL | FR | LFE | RC | FLC | FRC },
++ { .ca_id = 0x0c, .n_ch = 8,
++ .mask = FL | FR | RC | RL | RR },
++ { .ca_id = 0x18, .n_ch = 8,
++ .mask = FL | FR | RC | FLC | FRC },
++ { .ca_id = 0x17, .n_ch = 8,
++ .mask = FL | FR | LFE | FC | FLC | FRC },
++ { .ca_id = 0x16, .n_ch = 8,
++ .mask = FL | FR | FC | FLC | FRC },
++ { .ca_id = 0x15, .n_ch = 8,
++ .mask = FL | FR | LFE | FLC | FRC },
++ { .ca_id = 0x14, .n_ch = 8,
++ .mask = FL | FR | FLC | FRC },
++ { .ca_id = 0x0b, .n_ch = 8,
++ .mask = FL | FR | LFE | FC | RL | RR },
++ { .ca_id = 0x0a, .n_ch = 8,
++ .mask = FL | FR | FC | RL | RR },
++ { .ca_id = 0x09, .n_ch = 8,
++ .mask = FL | FR | LFE | RL | RR },
++ { .ca_id = 0x08, .n_ch = 8,
++ .mask = FL | FR | RL | RR },
++ { .ca_id = 0x07, .n_ch = 8,
++ .mask = FL | FR | LFE | FC | RC },
++ { .ca_id = 0x06, .n_ch = 8,
++ .mask = FL | FR | FC | RC },
++ { .ca_id = 0x05, .n_ch = 8,
++ .mask = FL | FR | LFE | RC },
++ { .ca_id = 0x04, .n_ch = 8,
++ .mask = FL | FR | RC },
++ { .ca_id = 0x03, .n_ch = 8,
++ .mask = FL | FR | LFE | FC },
++ { .ca_id = 0x02, .n_ch = 8,
++ .mask = FL | FR | FC },
++ { .ca_id = 0x01, .n_ch = 8,
++ .mask = FL | FR | LFE },
+ };
+
+ struct hdmi_codec_priv {
+@@ -374,7 +387,8 @@ static int hdmi_codec_chmap_ctl_get(struct snd_kcontrol *kcontrol,
+ struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
+ struct hdmi_codec_priv *hcp = info->private_data;
+
+- map = info->chmap[hcp->chmap_idx].map;
++ if (hcp->chmap_idx != HDMI_CODEC_CHMAP_IDX_UNKNOWN)
++ map = info->chmap[hcp->chmap_idx].map;
+
+ for (i = 0; i < info->max_channels; i++) {
+ if (hcp->chmap_idx == HDMI_CODEC_CHMAP_IDX_UNKNOWN)
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,59 @@
+From 9d475abbf29793acc2c085e862ee8abb60c88961 Mon Sep 17 00:00:00 2001
+From: Neil Armstrong <narmstrong@baylibre.com>
+Date: Thu, 14 Jan 2021 17:43:02 +0100
+Subject: [PATCH 25/73] WIP: mmc: meson-gx-mmc: set core clock phase to 270
+ degrees for AXG compatible controllers
+
+Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
+---
+ drivers/mmc/host/meson-gx-mmc.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c
+index a2aacbffc3bf..c16ac828b6f9 100644
+--- a/drivers/mmc/host/meson-gx-mmc.c
++++ b/drivers/mmc/host/meson-gx-mmc.c
+@@ -38,6 +38,7 @@
+ #define CLK_RX_PHASE_MASK GENMASK(13, 12)
+ #define CLK_PHASE_0 0
+ #define CLK_PHASE_180 2
++#define CLK_PHASE_270 3
+ #define CLK_V2_TX_DELAY_MASK GENMASK(19, 16)
+ #define CLK_V2_RX_DELAY_MASK GENMASK(23, 20)
+ #define CLK_V2_ALWAYS_ON BIT(24)
+@@ -136,6 +137,7 @@ struct meson_mmc_data {
+ unsigned int rx_delay_mask;
+ unsigned int always_on;
+ unsigned int adjust;
++ unsigned int clk_core_phase;
+ };
+
+ struct sd_emmc_desc {
+@@ -428,7 +430,7 @@ static int meson_mmc_clk_init(struct meson_host *host)
+ /* init SD_EMMC_CLOCK to sane defaults w/min clock rate */
+ clk_reg = CLK_ALWAYS_ON(host);
+ clk_reg |= CLK_DIV_MASK;
+- clk_reg |= FIELD_PREP(CLK_CORE_PHASE_MASK, CLK_PHASE_180);
++ clk_reg |= FIELD_PREP(CLK_CORE_PHASE_MASK, host->data->clk_core_phase);
+ clk_reg |= FIELD_PREP(CLK_TX_PHASE_MASK, CLK_PHASE_0);
+ clk_reg |= FIELD_PREP(CLK_RX_PHASE_MASK, CLK_PHASE_0);
+ writel(clk_reg, host->regs + SD_EMMC_CLOCK);
+@@ -1328,6 +1330,7 @@ static const struct meson_mmc_data meson_gx_data = {
+ .rx_delay_mask = CLK_V2_RX_DELAY_MASK,
+ .always_on = CLK_V2_ALWAYS_ON,
+ .adjust = SD_EMMC_ADJUST,
++ .clk_core_phase = CLK_PHASE_180,
+ };
+
+ static const struct meson_mmc_data meson_axg_data = {
+@@ -1335,6 +1338,7 @@ static const struct meson_mmc_data meson_axg_data = {
+ .rx_delay_mask = CLK_V3_RX_DELAY_MASK,
+ .always_on = CLK_V3_ALWAYS_ON,
+ .adjust = SD_EMMC_V3_ADJUST,
++ .clk_core_phase = CLK_PHASE_270,
+ };
+
+ static const struct of_device_id meson_mmc_of_match[] = {
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,32 @@
+From be4a8a8b236626776583abc7c0bc6a0cbe4ecf55 Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Thu, 13 Jan 2022 03:50:01 +0000
+Subject: [PATCH 26/73] WIP: arm64: dts: meson: add Broadcom WiFi to P212 dtsi
+
+The P212 has a combined WiFi/BT module. The BT side is already enabled
+in the dtsi but the WiFi side is not. Let's enable the WiFi module.
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
+index 05cb2f5e5c36..7055057d7942 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
+@@ -125,6 +125,11 @@
+
+ vmmc-supply = <&vddao_3v3>;
+ vqmmc-supply = <&vddio_boot>;
++
++ brcmf: wifi@1 {
++ reg = <1>;
++ compatible = "brcm,bcm4329-fmac";
++ };
+ };
+
+ /* SD card */
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,49 @@
+From a4e6681cdab0a1e3518ee3401e2b7ffba0363b90 Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Thu, 13 Jan 2022 03:56:12 +0000
+Subject: [PATCH 27/73] WIP: arm64: dts: meson: move pwm_ef node in P212 dtsi
+
+Cosmetic-only change to alpha-sort the pwm_ef node.
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ .../boot/dts/amlogic/meson-gxl-s905x-p212.dtsi | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
+index 7055057d7942..a150cc0e18ff 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
+@@ -97,6 +97,14 @@
+ pinctrl-names = "default";
+ };
+
++&pwm_ef {
++ status = "okay";
++ pinctrl-0 = <&pwm_e_pins>;
++ pinctrl-names = "default";
++ clocks = <&clkc CLKID_FCLK_DIV4>;
++ clock-names = "clkin0";
++};
++
+ &saradc {
+ status = "okay";
+ vref-supply = <&vddio_ao18>;
+@@ -170,14 +178,6 @@
+ vqmmc-supply = <&vddio_boot>;
+ };
+
+-&pwm_ef {
+- status = "okay";
+- pinctrl-0 = <&pwm_e_pins>;
+- pinctrl-names = "default";
+- clocks = <&clkc CLKID_FCLK_DIV4>;
+- clock-names = "clkin0";
+-};
+-
+ /* This is connected to the Bluetooth module: */
+ &uart_A {
+ status = "okay";
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,43 @@
+From 96b67dcbffe99d032c38bb393f8f3459b5df04cf Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Thu, 13 Jan 2022 03:58:58 +0000
+Subject: [PATCH 28/73] WIP: arm64: dts: meson: remove WiFi/BT nodes from
+ Khadas VIM1
+
+The Broadcom WiFi/BT SDIO nodes are now inherited from the P212 common dtsi
+so we can remove them from the VIM1 board dts.
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ .../dts/amlogic/meson-gxl-s905x-khadas-vim.dts | 15 ---------------
+ 1 file changed, 15 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
+index 24af15e18026..5ed1e9313003 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
+@@ -221,21 +221,6 @@
+
+ &sd_emmc_a {
+ max-frequency = <100000000>;
+-
+- brcmf: wifi@1 {
+- reg = <1>;
+- compatible = "brcm,bcm4329-fmac";
+- };
+-};
+-
+-&uart_A {
+- bluetooth {
+- compatible = "brcm,bcm43438-bt";
+- shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
+- max-speed = <2000000>;
+- clocks = <&wifi32k>;
+- clock-names = "lpo";
+- };
+ };
+
+ /* This is brought out on the Linux_RX (18) and Linux_TX (19) pins: */
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,109 @@
+From 193209275b80d4510bd47a52c029084b2fedf542 Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Tue, 18 Jan 2022 15:09:12 +0000
+Subject: [PATCH 29/73] WIP: arm64: dts: meson: set p212/p23x/q20x SDIO to
+ 100MHz
+
+Amlogic datasheets describe 50MHz max-frequency for SDIO on GXL/GXM but
+real-world tests on an assortment of GXL and GXM boards show noteable
+increases in throughput when max-frequency is 100MHz, so let's use it.
+
+Before results from a p231 device:
+
+Connecting to host 192.168.0.1, port 5201
+Reverse mode, remote host 192.168.0.1 is sending
+[ 5] local 192.168.0.41 port 42550 connected to 192.168.0.1 port 5201
+[ ID] Interval Transfer Bitrate
+[ 5] 0.00-1.00 sec 8.84 MBytes 74.2 Mbits/sec
+[ 5] 1.00-2.00 sec 9.60 MBytes 80.5 Mbits/sec
+[ 5] 2.00-3.00 sec 9.07 MBytes 76.1 Mbits/sec
+[ 5] 3.00-4.00 sec 9.14 MBytes 76.6 Mbits/sec
+[ 5] 4.00-5.00 sec 9.26 MBytes 77.7 Mbits/sec
+[ 5] 5.00-6.00 sec 9.08 MBytes 76.2 Mbits/sec
+[ 5] 6.00-7.00 sec 9.11 MBytes 76.4 Mbits/sec
+[ 5] 7.00-8.00 sec 8.65 MBytes 72.5 Mbits/sec
+[ 5] 8.00-9.00 sec 9.24 MBytes 77.5 Mbits/sec
+[ 5] 9.00-10.00 sec 8.57 MBytes 71.9 Mbits/sec
+- - - - - - - - - - - - - - - - - - - - - - - - -
+[ ID] Interval Transfer Bitrate Retr
+[ 5] 0.00-10.27 sec 94.1 MBytes 76.8 Mbits/sec 0 sender
+[ 5] 0.00-10.00 sec 90.6 MBytes 76.0 Mbits/sec receiver
+
+clock: 50000000 Hz
+actual clock: 50000000 Hz
+vdd: 21 (3.3 ~ 3.4 V)
+bus mode: 2 (push-pull)
+chip select: 0 (don't care)
+power mode: 2 (on)
+bus width: 2 (4 bits)
+timing spec: 2 (sd high-speed)
+signal voltage: 1 (1.80 V)
+driver type: 0 (driver type B)
+
+After results from a p231 device:
+
+Connecting to host 192.168.0.1, port 5201
+Reverse mode, remote host 192.168.0.1 is sending
+[ 5] local 192.168.0.41 port 58534 connected to 192.168.0.1 port 5201
+[ ID] Interval Transfer Bitrate
+[ 5] 0.00-1.00 sec 12.6 MBytes 106 Mbits/sec
+[ 5] 1.00-2.00 sec 13.0 MBytes 109 Mbits/sec
+[ 5] 2.00-3.00 sec 12.8 MBytes 107 Mbits/sec
+[ 5] 3.00-4.00 sec 13.2 MBytes 111 Mbits/sec
+[ 5] 4.00-5.00 sec 12.4 MBytes 104 Mbits/sec
+[ 5] 5.00-6.00 sec 11.2 MBytes 93.9 Mbits/sec
+[ 5] 6.00-7.00 sec 12.3 MBytes 103 Mbits/sec
+[ 5] 7.00-8.00 sec 12.3 MBytes 103 Mbits/sec
+[ 5] 8.00-9.00 sec 12.5 MBytes 105 Mbits/sec
+[ 5] 9.00-10.00 sec 12.3 MBytes 103 Mbits/sec
+- - - - - - - - - - - - - - - - - - - - - - - - -
+[ ID] Interval Transfer Bitrate Retr
+[ 5] 0.00-10.22 sec 127 MBytes 104 Mbits/sec 0 sender
+[ 5] 0.00-10.00 sec 125 MBytes 105 Mbits/sec receiver
+
+clock: 100000000 Hz
+actual clock: 100000000 Hz
+vdd: 21 (3.3 ~ 3.4 V)
+bus mode: 2 (push-pull)
+chip select: 0 (don't care)
+power mode: 2 (on)
+bus width: 2 (4 bits)
+timing spec: 6 (sd uhs SDR104)
+signal voltage: 1 (1.80 V)
+driver type: 0 (driver type B)
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi | 2 +-
+ arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
+index dafc841f7c16..8d315508360d 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
++++ b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
+@@ -259,7 +259,7 @@
+
+ bus-width = <4>;
+ cap-sd-highspeed;
+- max-frequency = <50000000>;
++ max-frequency = <100000000>;
+
+ non-removable;
+ disable-wp;
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
+index a150cc0e18ff..b3d7b8613d6d 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
+@@ -121,7 +121,7 @@
+
+ bus-width = <4>;
+ cap-sd-highspeed;
+- max-frequency = <50000000>;
++ max-frequency = <100000000>;
+
+ non-removable;
+ disable-wp;
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,47 @@
+From e5a3f942e0191001771ecec4eeb0cfc6312727a1 Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Wed, 19 Jan 2022 06:45:06 +0000
+Subject: [PATCH 30/73] WIP: arm64: dts: meson: add UHS SDIO capabilities to
+ p212/p23x/q20x
+
+Add UHS capabilities to the SDIO node to enable 100MHz speeds.
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi | 4 ++++
+ arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi | 4 ++++
+ 2 files changed, 8 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
+index 8d315508360d..b0d008fc5f7a 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
++++ b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
+@@ -259,6 +259,10 @@
+
+ bus-width = <4>;
+ cap-sd-highspeed;
++ sd-uhs-sdr12;
++ sd-uhs-sdr25;
++ sd-uhs-sdr50;
++ sd-uhs-sdr104;
+ max-frequency = <100000000>;
+
+ non-removable;
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
+index b3d7b8613d6d..6eec4e81592b 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
+@@ -121,6 +121,10 @@
+
+ bus-width = <4>;
+ cap-sd-highspeed;
++ sd-uhs-sdr12;
++ sd-uhs-sdr25;
++ sd-uhs-sdr50;
++ sd-uhs-sdr104;
+ max-frequency = <100000000>;
+
+ non-removable;
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,32 @@
+From f9949b67a813b574134869de01224f589e0af092 Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Tue, 18 Jan 2022 15:18:32 +0000
+Subject: [PATCH 31/73] WIP: arm64: dts: meson: remove SDIO node from Khadas
+ VIM1
+
+Now that SDIO 100MHz max-frequency is inherited from the p212 dtsi we
+can drop the node from the board dts.
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
+index 5ed1e9313003..fb0dd920882f 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
+@@ -219,10 +219,6 @@
+ pinctrl-0 = <&pwm_e_pins>, <&pwm_f_clk_pins>;
+ };
+
+-&sd_emmc_a {
+- max-frequency = <100000000>;
+-};
+-
+ /* This is brought out on the Linux_RX (18) and Linux_TX (19) pins: */
+ &uart_AO {
+ status = "okay";
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,109 @@
+From 841690704fda49df673b17cd7847f8fc6d14026c Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Thu, 13 Jan 2022 04:30:44 +0000
+Subject: [PATCH 32/73] WIP: arm64: dts: meson: add audio playback to
+ S905X-P212 dts
+
+Add support for the HDMI and Analogue i2s audio outputs.
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ .../boot/dts/amlogic/meson-gxl-s905x-p212.dts | 70 +++++++++++++++++++
+ 1 file changed, 70 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts
+index 2602940c2077..c2bc7cec476d 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts
++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts
+@@ -7,11 +7,19 @@
+ /dts-v1/;
+
+ #include "meson-gxl-s905x-p212.dtsi"
++#include <dt-bindings/sound/meson-aiu.h>
+
+ / {
+ compatible = "amlogic,p212", "amlogic,s905x", "amlogic,meson-gxl";
+ model = "Amlogic Meson GXL (S905X) P212 Development Board";
+
++ dio2133: analog-amplifier {
++ compatible = "simple-audio-amplifier";
++ sound-name-prefix = "AU2";
++ VCC-supply = <&hdmi_5v>;
++ enable-gpios = <&gpio GPIOH_5 GPIO_ACTIVE_HIGH>;
++ };
++
+ cvbs-connector {
+ compatible = "composite-video-connector";
+
+@@ -32,6 +40,68 @@
+ };
+ };
+ };
++
++ sound {
++ compatible = "amlogic,gx-sound-card";
++ model = "S905X-P212";
++ audio-aux-devs = <&dio2133>;
++ audio-widgets = "Line", "Lineout";
++ audio-routing = "AU2 INL", "ACODEC LOLN",
++ "AU2 INR", "ACODEC LORN",
++ "Lineout", "AU2 OUTL",
++ "Lineout", "AU2 OUTR";
++ assigned-clocks = <&clkc CLKID_MPLL0>,
++ <&clkc CLKID_MPLL1>,
++ <&clkc CLKID_MPLL2>;
++ assigned-clock-parents = <0>, <0>, <0>;
++ assigned-clock-rates = <294912000>,
++ <270950400>,
++ <393216000>;
++ status = "okay";
++
++ dai-link-0 {
++ sound-dai = <&aiu AIU_CPU CPU_I2S_FIFO>;
++ };
++
++ dai-link-1 {
++ sound-dai = <&aiu AIU_CPU CPU_I2S_ENCODER>;
++ dai-format = "i2s";
++ mclk-fs = <256>;
++
++ codec-0 {
++ sound-dai = <&aiu AIU_HDMI CTRL_I2S>;
++ };
++
++ codec-1 {
++ sound-dai = <&aiu AIU_ACODEC CTRL_I2S>;
++ };
++ };
++
++ dai-link-2 {
++ sound-dai = <&aiu AIU_HDMI CTRL_OUT>;
++
++ codec-0 {
++ sound-dai = <&hdmi_tx>;
++ };
++ };
++
++ dai-link-3 {
++ sound-dai = <&aiu AIU_ACODEC CTRL_OUT>;
++
++ codec-0 {
++ sound-dai = <&acodec>;
++ };
++ };
++ };
++};
++
++&acodec {
++ AVDD-supply = <&vddio_ao18>;
++ status = "okay";
++};
++
++&aiu {
++ status = "okay";
+ };
+
+ &cec_AO {
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,29 @@
+From b07432a29e196337c9e9506a0b1ece3a2c5d2944 Mon Sep 17 00:00:00 2001
+From: benjamin545 <benjamin545@gmail.com>
+Date: Thu, 15 Jul 2021 14:32:33 -0400
+Subject: [PATCH 33/73] WIP: drivers: meson: vdec: remove redundant if
+ statement
+
+checking if sess->fmt_out->pixfmt is V4L2_PIX_FMT_VP9 was already done
+as a condition to enter the if statement where this additional check is performed
+---
+ drivers/staging/media/meson/vdec/esparser.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/staging/media/meson/vdec/esparser.c b/drivers/staging/media/meson/vdec/esparser.c
+index 86ccc8937afc..7b15fc54efe4 100644
+--- a/drivers/staging/media/meson/vdec/esparser.c
++++ b/drivers/staging/media/meson/vdec/esparser.c
+@@ -314,8 +314,7 @@ esparser_queue(struct amvdec_session *sess, struct vb2_v4l2_buffer *vbuf)
+ num_dst_bufs = codec_ops->num_pending_bufs(sess);
+
+ num_dst_bufs += v4l2_m2m_num_dst_bufs_ready(sess->m2m_ctx);
+- if (sess->fmt_out->pixfmt == V4L2_PIX_FMT_VP9)
+- num_dst_bufs -= 3;
++ num_dst_bufs -= 3;
+
+ if (esparser_vififo_get_free_space(sess) < payload_size ||
+ atomic_read(&sess->esparser_queued_bufs) >= num_dst_bufs)
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,586 @@
+From 44bcd5abdcc043dbabd7af356ab7b81972b806d3 Mon Sep 17 00:00:00 2001
+From: benjamin545 <benjamin545@gmail.com>
+Date: Thu, 15 Jul 2021 16:32:39 -0400
+Subject: [PATCH 34/73] WIP: drivers: meson: vdec: improve mmu and fbc handling
+ and add 10 bit handling
+
+---
+ drivers/staging/media/meson/vdec/codec_h264.c | 3 +-
+ .../media/meson/vdec/codec_hevc_common.c | 164 +++++++++++-------
+ .../media/meson/vdec/codec_hevc_common.h | 3 +-
+ drivers/staging/media/meson/vdec/codec_vp9.c | 36 ++--
+ drivers/staging/media/meson/vdec/esparser.c | 1 +
+ drivers/staging/media/meson/vdec/vdec.h | 1 +
+ .../staging/media/meson/vdec/vdec_helpers.c | 46 +++--
+ .../staging/media/meson/vdec/vdec_helpers.h | 10 +-
+ 8 files changed, 163 insertions(+), 101 deletions(-)
+
+diff --git a/drivers/staging/media/meson/vdec/codec_h264.c b/drivers/staging/media/meson/vdec/codec_h264.c
+index c61128fc4bb9..d53c9a464bde 100644
+--- a/drivers/staging/media/meson/vdec/codec_h264.c
++++ b/drivers/staging/media/meson/vdec/codec_h264.c
+@@ -353,7 +353,8 @@ static void codec_h264_src_change(struct amvdec_session *sess)
+ frame_width, frame_height, crop_right, crop_bottom);
+
+ codec_h264_set_par(sess);
+- amvdec_src_change(sess, frame_width, frame_height, h264->max_refs + 5);
++ amvdec_src_change(sess, frame_width, frame_height,
++ h264->max_refs + 5, 8);
+ }
+
+ /*
+diff --git a/drivers/staging/media/meson/vdec/codec_hevc_common.c b/drivers/staging/media/meson/vdec/codec_hevc_common.c
+index 0315cc0911cd..d6ed82dc93ca 100644
+--- a/drivers/staging/media/meson/vdec/codec_hevc_common.c
++++ b/drivers/staging/media/meson/vdec/codec_hevc_common.c
+@@ -30,8 +30,11 @@ const u16 vdec_hevc_parser_cmd[] = {
+ void codec_hevc_setup_decode_head(struct amvdec_session *sess, int is_10bit)
+ {
+ struct amvdec_core *core = sess->core;
+- u32 body_size = amvdec_am21c_body_size(sess->width, sess->height);
+- u32 head_size = amvdec_am21c_head_size(sess->width, sess->height);
++ u32 use_mmu = codec_hevc_use_mmu(core->platform->revision,
++ sess->pixfmt_cap, is_10bit);
++ u32 body_size = amvdec_amfbc_body_size(sess->width, sess->height,
++ is_10bit, use_mmu);
++ u32 head_size = amvdec_amfbc_head_size(sess->width, sess->height);
+
+ if (!codec_hevc_use_fbc(sess->pixfmt_cap, is_10bit)) {
+ /* Enable 2-plane reference read mode */
+@@ -39,9 +42,17 @@ void codec_hevc_setup_decode_head(struct amvdec_session *sess, int is_10bit)
+ return;
+ }
+
++ /* enable mem saving mode for 8-bit */
++ if (!is_10bit)
++ amvdec_write_dos_bits(core, HEVC_SAO_CTRL5, BIT(9));
++ else
++ amvdec_clear_dos_bits(core, HEVC_SAO_CTRL5, BIT(9));
++
+ if (codec_hevc_use_mmu(core->platform->revision,
+ sess->pixfmt_cap, is_10bit))
+ amvdec_write_dos(core, HEVCD_MPP_DECOMP_CTL1, BIT(4));
++ else if (!is_10bit)
++ amvdec_write_dos(core, HEVCD_MPP_DECOMP_CTL1, BIT(3));
+ else
+ amvdec_write_dos(core, HEVCD_MPP_DECOMP_CTL1, 0);
+
+@@ -73,7 +84,7 @@ static void codec_hevc_setup_buffers_gxbb(struct amvdec_session *sess,
+
+ idx = vb->index;
+
+- if (codec_hevc_use_downsample(sess->pixfmt_cap, is_10bit))
++ if (codec_hevc_use_fbc(sess->pixfmt_cap, is_10bit))
+ buf_y_paddr = comm->fbc_buffer_paddr[idx];
+ else
+ buf_y_paddr = vb2_dma_contig_plane_dma_addr(vb, 0);
+@@ -114,8 +125,8 @@ static void codec_hevc_setup_buffers_gxl(struct amvdec_session *sess,
+ {
+ struct amvdec_core *core = sess->core;
+ struct v4l2_m2m_buffer *buf;
+- u32 revision = core->platform->revision;
+ u32 pixfmt_cap = sess->pixfmt_cap;
++ const u32 revision = core->platform->revision;
+ int i;
+
+ amvdec_write_dos(core, HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR,
+@@ -127,12 +138,14 @@ static void codec_hevc_setup_buffers_gxl(struct amvdec_session *sess,
+ dma_addr_t buf_uv_paddr = 0;
+ u32 idx = vb->index;
+
+- if (codec_hevc_use_mmu(revision, pixfmt_cap, is_10bit))
+- buf_y_paddr = comm->mmu_header_paddr[idx];
+- else if (codec_hevc_use_downsample(pixfmt_cap, is_10bit))
+- buf_y_paddr = comm->fbc_buffer_paddr[idx];
+- else
+- buf_y_paddr = vb2_dma_contig_plane_dma_addr(vb, 0);
++ if (codec_hevc_use_downsample(pixfmt_cap, is_10bit)) {
++ if (codec_hevc_use_mmu(revision, pixfmt_cap, is_10bit))
++ buf_y_paddr = comm->mmu_header_paddr[idx];
++ else
++ buf_y_paddr = comm->fbc_buffer_paddr[idx];
++ } else {
++ buf_y_paddr = vb2_dma_contig_plane_dma_addr(vb, 0);
++ }
+
+ amvdec_write_dos(core, HEVCD_MPP_ANC2AXI_TBL_DATA,
+ buf_y_paddr >> 5);
+@@ -150,60 +163,67 @@ static void codec_hevc_setup_buffers_gxl(struct amvdec_session *sess,
+ amvdec_write_dos(core, HEVCD_MPP_ANC_CANVAS_DATA_ADDR, 0);
+ }
+
+-void codec_hevc_free_fbc_buffers(struct amvdec_session *sess,
++void codec_hevc_free_mmu_headers(struct amvdec_session *sess,
+ struct codec_hevc_common *comm)
+ {
+ struct device *dev = sess->core->dev;
+- u32 am21_size = amvdec_am21c_size(sess->width, sess->height);
+ int i;
+
+ for (i = 0; i < MAX_REF_PIC_NUM; ++i) {
+- if (comm->fbc_buffer_vaddr[i]) {
+- dma_free_coherent(dev, am21_size,
+- comm->fbc_buffer_vaddr[i],
+- comm->fbc_buffer_paddr[i]);
+- comm->fbc_buffer_vaddr[i] = NULL;
++ if (comm->mmu_header_vaddr[i]) {
++ dma_free_coherent(dev, MMU_COMPRESS_HEADER_SIZE,
++ comm->mmu_header_vaddr[i],
++ comm->mmu_header_paddr[i]);
++ comm->mmu_header_vaddr[i] = NULL;
+ }
+ }
+ }
+-EXPORT_SYMBOL_GPL(codec_hevc_free_fbc_buffers);
++EXPORT_SYMBOL_GPL(codec_hevc_free_mmu_headers);
+
+-static int codec_hevc_alloc_fbc_buffers(struct amvdec_session *sess,
++static int codec_hevc_alloc_mmu_headers(struct amvdec_session *sess,
+ struct codec_hevc_common *comm)
+ {
+ struct device *dev = sess->core->dev;
+ struct v4l2_m2m_buffer *buf;
+- u32 am21_size = amvdec_am21c_size(sess->width, sess->height);
+
+ v4l2_m2m_for_each_dst_buf(sess->m2m_ctx, buf) {
+ u32 idx = buf->vb.vb2_buf.index;
+ dma_addr_t paddr;
+- void *vaddr = dma_alloc_coherent(dev, am21_size, &paddr,
+- GFP_KERNEL);
++ void *vaddr = dma_alloc_coherent(dev, MMU_COMPRESS_HEADER_SIZE,
++ &paddr, GFP_KERNEL);
+ if (!vaddr) {
+- codec_hevc_free_fbc_buffers(sess, comm);
++ codec_hevc_free_mmu_headers(sess, comm);
+ return -ENOMEM;
+ }
+
+- comm->fbc_buffer_vaddr[idx] = vaddr;
+- comm->fbc_buffer_paddr[idx] = paddr;
++ comm->mmu_header_vaddr[idx] = vaddr;
++ comm->mmu_header_paddr[idx] = paddr;
+ }
+
+ return 0;
+ }
+
+-void codec_hevc_free_mmu_headers(struct amvdec_session *sess,
++void codec_hevc_free_fbc_buffers(struct amvdec_session *sess,
+ struct codec_hevc_common *comm)
+ {
+ struct device *dev = sess->core->dev;
++ u32 use_mmu;
++ u32 am21_size;
+ int i;
+
++ use_mmu = codec_hevc_use_mmu(sess->core->platform->revision,
++ sess->pixfmt_cap,
++ sess->bitdepth == 10 ? 1 : 0);
++
++ am21_size = amvdec_amfbc_size(sess->width, sess->height,
++ sess->bitdepth == 10 ? 1 : 0, use_mmu);
++
+ for (i = 0; i < MAX_REF_PIC_NUM; ++i) {
+- if (comm->mmu_header_vaddr[i]) {
+- dma_free_coherent(dev, MMU_COMPRESS_HEADER_SIZE,
+- comm->mmu_header_vaddr[i],
+- comm->mmu_header_paddr[i]);
+- comm->mmu_header_vaddr[i] = NULL;
++ if (comm->fbc_buffer_vaddr[i]) {
++ dma_free_coherent(dev, am21_size,
++ comm->fbc_buffer_vaddr[i],
++ comm->fbc_buffer_paddr[i]);
++ comm->fbc_buffer_vaddr[i] = NULL;
+ }
+ }
+
+@@ -213,33 +233,49 @@ void codec_hevc_free_mmu_headers(struct amvdec_session *sess,
+ comm->mmu_map_paddr);
+ comm->mmu_map_vaddr = NULL;
+ }
++
++ codec_hevc_free_mmu_headers(sess, comm);
+ }
+-EXPORT_SYMBOL_GPL(codec_hevc_free_mmu_headers);
++EXPORT_SYMBOL_GPL(codec_hevc_free_fbc_buffers);
+
+-static int codec_hevc_alloc_mmu_headers(struct amvdec_session *sess,
++static int codec_hevc_alloc_fbc_buffers(struct amvdec_session *sess,
+ struct codec_hevc_common *comm)
+ {
+ struct device *dev = sess->core->dev;
+ struct v4l2_m2m_buffer *buf;
++ u32 use_mmu;
++ u32 am21_size;
++ const u32 revision = sess->core->platform->revision;
++ const u32 is_10bit = sess->bitdepth == 10 ? 1 : 0;
++ int ret;
+
+- comm->mmu_map_vaddr = dma_alloc_coherent(dev, MMU_MAP_SIZE,
+- &comm->mmu_map_paddr,
+- GFP_KERNEL);
+- if (!comm->mmu_map_vaddr)
+- return -ENOMEM;
++ use_mmu = codec_hevc_use_mmu(revision, sess->pixfmt_cap,
++ is_10bit);
++
++ am21_size = amvdec_amfbc_size(sess->width, sess->height,
++ is_10bit, use_mmu);
+
+ v4l2_m2m_for_each_dst_buf(sess->m2m_ctx, buf) {
+ u32 idx = buf->vb.vb2_buf.index;
+ dma_addr_t paddr;
+- void *vaddr = dma_alloc_coherent(dev, MMU_COMPRESS_HEADER_SIZE,
+- &paddr, GFP_KERNEL);
++ void *vaddr = dma_alloc_coherent(dev, am21_size, &paddr,
++ GFP_KERNEL);
+ if (!vaddr) {
+- codec_hevc_free_mmu_headers(sess, comm);
++ codec_hevc_free_fbc_buffers(sess, comm);
+ return -ENOMEM;
+ }
+
+- comm->mmu_header_vaddr[idx] = vaddr;
+- comm->mmu_header_paddr[idx] = paddr;
++ comm->fbc_buffer_vaddr[idx] = vaddr;
++ comm->fbc_buffer_paddr[idx] = paddr;
++ }
++
++ if (codec_hevc_use_mmu(revision, sess->pixfmt_cap, is_10bit) &&
++ codec_hevc_use_downsample(sess->pixfmt_cap, is_10bit)) {
++ ret = codec_hevc_alloc_mmu_headers(sess, comm);
++ if (ret) {
++ codec_hevc_free_fbc_buffers(sess, comm);
++ return ret;
++ }
+ }
+
+ return 0;
+@@ -250,21 +286,24 @@ int codec_hevc_setup_buffers(struct amvdec_session *sess,
+ int is_10bit)
+ {
+ struct amvdec_core *core = sess->core;
++ struct device *dev = core->dev;
+ int ret;
+
+- if (codec_hevc_use_downsample(sess->pixfmt_cap, is_10bit)) {
+- ret = codec_hevc_alloc_fbc_buffers(sess, comm);
+- if (ret)
+- return ret;
++ if (codec_hevc_use_mmu(core->platform->revision,
++ sess->pixfmt_cap, is_10bit)) {
++ comm->mmu_map_vaddr = dma_alloc_coherent(dev, MMU_MAP_SIZE,
++ &comm->mmu_map_paddr,
++ GFP_KERNEL);
++ if (!comm->mmu_map_vaddr)
++ return -ENOMEM;
+ }
+
+ if (codec_hevc_use_mmu(core->platform->revision,
+- sess->pixfmt_cap, is_10bit)) {
+- ret = codec_hevc_alloc_mmu_headers(sess, comm);
+- if (ret) {
+- codec_hevc_free_fbc_buffers(sess, comm);
+- return ret;
+- }
++ sess->pixfmt_cap, is_10bit) ||
++ codec_hevc_use_downsample(sess->pixfmt_cap, is_10bit)) {
++ ret = codec_hevc_alloc_fbc_buffers(sess, comm);
++ if (ret)
++ return ret;
+ }
+
+ if (core->platform->revision == VDEC_REVISION_GXBB)
+@@ -278,19 +317,24 @@ EXPORT_SYMBOL_GPL(codec_hevc_setup_buffers);
+
+ void codec_hevc_fill_mmu_map(struct amvdec_session *sess,
+ struct codec_hevc_common *comm,
+- struct vb2_buffer *vb)
++ struct vb2_buffer *vb,
++ u32 is_10bit)
+ {
+- u32 size = amvdec_am21c_size(sess->width, sess->height);
+- u32 nb_pages = size / PAGE_SIZE;
++ u32 use_mmu;
++ u32 size;
++ u32 nb_pages;
+ u32 *mmu_map = comm->mmu_map_vaddr;
+ u32 first_page;
+ u32 i;
+
+- if (sess->pixfmt_cap == V4L2_PIX_FMT_NV12M)
+- first_page = comm->fbc_buffer_paddr[vb->index] >> PAGE_SHIFT;
+- else
+- first_page = vb2_dma_contig_plane_dma_addr(vb, 0) >> PAGE_SHIFT;
++ use_mmu = codec_hevc_use_mmu(sess->core->platform->revision,
++ sess->pixfmt_cap, is_10bit);
++
++ size = amvdec_amfbc_size(sess->width, sess->height, is_10bit,
++ use_mmu);
+
++ nb_pages = size / PAGE_SIZE;
++ first_page = comm->fbc_buffer_paddr[vb->index] >> PAGE_SHIFT;
+ for (i = 0; i < nb_pages; ++i)
+ mmu_map[i] = first_page + i;
+ }
+diff --git a/drivers/staging/media/meson/vdec/codec_hevc_common.h b/drivers/staging/media/meson/vdec/codec_hevc_common.h
+index cf072b8a9da2..13f9f1d90a94 100644
+--- a/drivers/staging/media/meson/vdec/codec_hevc_common.h
++++ b/drivers/staging/media/meson/vdec/codec_hevc_common.h
+@@ -64,6 +64,7 @@ int codec_hevc_setup_buffers(struct amvdec_session *sess,
+
+ void codec_hevc_fill_mmu_map(struct amvdec_session *sess,
+ struct codec_hevc_common *comm,
+- struct vb2_buffer *vb);
++ struct vb2_buffer *vb,
++ u32 is_10bit);
+
+ #endif
+diff --git a/drivers/staging/media/meson/vdec/codec_vp9.c b/drivers/staging/media/meson/vdec/codec_vp9.c
+index 897f5d7a6aad..bfc312ec2a56 100644
+--- a/drivers/staging/media/meson/vdec/codec_vp9.c
++++ b/drivers/staging/media/meson/vdec/codec_vp9.c
+@@ -458,12 +458,6 @@ struct codec_vp9 {
+ struct list_head ref_frames_list;
+ u32 frames_num;
+
+- /* In case of downsampling (decoding with FBC but outputting in NV12M),
+- * we need to allocate additional buffers for FBC.
+- */
+- void *fbc_buffer_vaddr[MAX_REF_PIC_NUM];
+- dma_addr_t fbc_buffer_paddr[MAX_REF_PIC_NUM];
+-
+ int ref_frame_map[REF_FRAMES];
+ int next_ref_frame_map[REF_FRAMES];
+ struct vp9_frame *frame_refs[REFS_PER_FRAME];
+@@ -901,11 +895,8 @@ static void codec_vp9_set_sao(struct amvdec_session *sess,
+ buf_y_paddr =
+ vb2_dma_contig_plane_dma_addr(vb, 0);
+
+- if (codec_hevc_use_fbc(sess->pixfmt_cap, vp9->is_10bit)) {
+- val = amvdec_read_dos(core, HEVC_SAO_CTRL5) & ~0xff0200;
+- amvdec_write_dos(core, HEVC_SAO_CTRL5, val);
+- amvdec_write_dos(core, HEVC_CM_BODY_START_ADDR, buf_y_paddr);
+- }
++ if (codec_hevc_use_fbc(sess->pixfmt_cap, vp9->is_10bit))
++ amvdec_write_dos(core, HEVC_CM_BODY_START_ADDR, buf_y_paddr);
+
+ if (sess->pixfmt_cap == V4L2_PIX_FMT_NV12M) {
+ buf_y_paddr =
+@@ -920,8 +911,12 @@ static void codec_vp9_set_sao(struct amvdec_session *sess,
+
+ if (codec_hevc_use_mmu(core->platform->revision, sess->pixfmt_cap,
+ vp9->is_10bit)) {
+- amvdec_write_dos(core, HEVC_CM_HEADER_START_ADDR,
+- vp9->common.mmu_header_paddr[vb->index]);
++ dma_addr_t header_adr;
++ if (codec_hevc_use_downsample(sess->pixfmt_cap, vp9->is_10bit))
++ header_adr = vp9->common.mmu_header_paddr[vb->index];
++ else
++ header_adr = vb2_dma_contig_plane_dma_addr(vb, 0);
++ amvdec_write_dos(core, HEVC_CM_HEADER_START_ADDR, header_adr);
+ /* use HEVC_CM_HEADER_START_ADDR */
+ amvdec_write_dos_bits(core, HEVC_SAO_CTRL5, BIT(10));
+ }
+@@ -1148,9 +1143,13 @@ static void codec_vp9_set_mc(struct amvdec_session *sess,
+ {
+ struct amvdec_core *core = sess->core;
+ u32 scale = 0;
++ u32 use_mmu;
+ u32 sz;
+ int i;
+
++ use_mmu = codec_hevc_use_mmu(core->platform->revision,
++ sess->pixfmt_cap, vp9->is_10bit);
++
+ amvdec_write_dos(core, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, 1);
+ codec_vp9_set_refs(sess, vp9);
+ amvdec_write_dos(core, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
+@@ -1166,8 +1165,9 @@ static void codec_vp9_set_mc(struct amvdec_session *sess,
+ vp9->frame_refs[i]->height != vp9->height)
+ scale = 1;
+
+- sz = amvdec_am21c_body_size(vp9->frame_refs[i]->width,
+- vp9->frame_refs[i]->height);
++ sz = amvdec_amfbc_body_size(vp9->frame_refs[i]->width,
++ vp9->frame_refs[i]->height,
++ vp9->is_10bit, use_mmu);
+
+ amvdec_write_dos(core, VP9D_MPP_REFINFO_DATA,
+ vp9->frame_refs[i]->width);
+@@ -1283,7 +1283,8 @@ static void codec_vp9_process_frame(struct amvdec_session *sess)
+ if (codec_hevc_use_mmu(core->platform->revision, sess->pixfmt_cap,
+ vp9->is_10bit))
+ codec_hevc_fill_mmu_map(sess, &vp9->common,
+- &vp9->cur_frame->vbuf->vb2_buf);
++ &vp9->cur_frame->vbuf->vb2_buf,
++ vp9->is_10bit);
+
+ intra_only = param->p.show_frame ? 0 : param->p.intra_only;
+
+@@ -2132,7 +2133,8 @@ static irqreturn_t codec_vp9_threaded_isr(struct amvdec_session *sess)
+
+ codec_vp9_fetch_rpm(sess);
+ if (codec_vp9_process_rpm(vp9)) {
+- amvdec_src_change(sess, vp9->width, vp9->height, 16);
++ amvdec_src_change(sess, vp9->width, vp9->height, 16,
++ vp9->is_10bit ? 10 : 8);
+
+ /* No frame is actually processed */
+ vp9->cur_frame = NULL;
+diff --git a/drivers/staging/media/meson/vdec/esparser.c b/drivers/staging/media/meson/vdec/esparser.c
+index 7b15fc54efe4..5d2273d53d02 100644
+--- a/drivers/staging/media/meson/vdec/esparser.c
++++ b/drivers/staging/media/meson/vdec/esparser.c
+@@ -319,6 +319,7 @@ esparser_queue(struct amvdec_session *sess, struct vb2_v4l2_buffer *vbuf)
+ if (esparser_vififo_get_free_space(sess) < payload_size ||
+ atomic_read(&sess->esparser_queued_bufs) >= num_dst_bufs)
+ return -EAGAIN;
++
+ } else if (esparser_vififo_get_free_space(sess) < payload_size) {
+ return -EAGAIN;
+ }
+diff --git a/drivers/staging/media/meson/vdec/vdec.h b/drivers/staging/media/meson/vdec/vdec.h
+index 0906b8fb5cc6..a48170fe4cff 100644
+--- a/drivers/staging/media/meson/vdec/vdec.h
++++ b/drivers/staging/media/meson/vdec/vdec.h
+@@ -244,6 +244,7 @@ struct amvdec_session {
+ u32 width;
+ u32 height;
+ u32 colorspace;
++ u32 bitdepth;
+ u8 ycbcr_enc;
+ u8 quantization;
+ u8 xfer_func;
+diff --git a/drivers/staging/media/meson/vdec/vdec_helpers.c b/drivers/staging/media/meson/vdec/vdec_helpers.c
+index 7d2a75653250..d684057509bf 100644
+--- a/drivers/staging/media/meson/vdec/vdec_helpers.c
++++ b/drivers/staging/media/meson/vdec/vdec_helpers.c
+@@ -50,32 +50,40 @@ void amvdec_write_parser(struct amvdec_core *core, u32 reg, u32 val)
+ }
+ EXPORT_SYMBOL_GPL(amvdec_write_parser);
+
+-/* 4 KiB per 64x32 block */
+-u32 amvdec_am21c_body_size(u32 width, u32 height)
++/* AMFBC body is made out of 64x32 blocks with varying block size */
++u32 amvdec_amfbc_body_size(u32 width, u32 height, u32 is_10bit, u32 use_mmu)
+ {
+ u32 width_64 = ALIGN(width, 64) / 64;
+ u32 height_32 = ALIGN(height, 32) / 32;
++ u32 blk_size = 4096;
+
+- return SZ_4K * width_64 * height_32;
++ if (!is_10bit) {
++ if (use_mmu)
++ blk_size = 3200;
++ else
++ blk_size = 3072;
++ }
++
++ return blk_size * width_64 * height_32;
+ }
+-EXPORT_SYMBOL_GPL(amvdec_am21c_body_size);
++EXPORT_SYMBOL_GPL(amvdec_amfbc_body_size);
+
+ /* 32 bytes per 128x64 block */
+-u32 amvdec_am21c_head_size(u32 width, u32 height)
++u32 amvdec_amfbc_head_size(u32 width, u32 height)
+ {
+ u32 width_128 = ALIGN(width, 128) / 128;
+ u32 height_64 = ALIGN(height, 64) / 64;
+
+ return 32 * width_128 * height_64;
+ }
+-EXPORT_SYMBOL_GPL(amvdec_am21c_head_size);
++EXPORT_SYMBOL_GPL(amvdec_amfbc_head_size);
+
+-u32 amvdec_am21c_size(u32 width, u32 height)
++u32 amvdec_amfbc_size(u32 width, u32 height, u32 is_10bit, u32 use_mmu)
+ {
+- return ALIGN(amvdec_am21c_body_size(width, height) +
+- amvdec_am21c_head_size(width, height), SZ_64K);
++ return ALIGN(amvdec_amfbc_body_size(width, height, is_10bit, use_mmu) +
++ amvdec_amfbc_head_size(width, height), SZ_64K);
+ }
+-EXPORT_SYMBOL_GPL(amvdec_am21c_size);
++EXPORT_SYMBOL_GPL(amvdec_amfbc_size);
+
+ static int canvas_alloc(struct amvdec_session *sess, u8 *canvas_id)
+ {
+@@ -440,7 +448,7 @@ void amvdec_set_par_from_dar(struct amvdec_session *sess,
+ EXPORT_SYMBOL_GPL(amvdec_set_par_from_dar);
+
+ void amvdec_src_change(struct amvdec_session *sess, u32 width,
+- u32 height, u32 dpb_size)
++ u32 height, u32 dpb_size, u32 bitdepth)
+ {
+ static const struct v4l2_event ev = {
+ .type = V4L2_EVENT_SOURCE_CHANGE,
+@@ -448,25 +456,27 @@ void amvdec_src_change(struct amvdec_session *sess, u32 width,
+
+ v4l2_ctrl_s_ctrl(sess->ctrl_min_buf_capture, dpb_size);
+
++ sess->bitdepth = bitdepth;
++
+ /*
+ * Check if the capture queue is already configured well for our
+- * usecase. If so, keep decoding with it and do not send the event
++ * usecase. If so, keep decoding with it.
+ */
+ if (sess->streamon_cap &&
+ sess->width == width &&
+ sess->height == height &&
+ dpb_size <= sess->num_dst_bufs) {
+ sess->fmt_out->codec_ops->resume(sess);
+- return;
+- }
++ } else {
++ sess->status = STATUS_NEEDS_RESUME;
++ sess->changed_format = 0;
++ }
+
+- sess->changed_format = 0;
+ sess->width = width;
+ sess->height = height;
+- sess->status = STATUS_NEEDS_RESUME;
+
+- dev_dbg(sess->core->dev, "Res. changed (%ux%u), DPB size %u\n",
+- width, height, dpb_size);
++ dev_dbg(sess->core->dev, "Res. changed (%ux%u), DPB %u, bitdepth %u\n",
++ width, height, dpb_size, bitdepth);
+ v4l2_event_queue_fh(&sess->fh, &ev);
+ }
+ EXPORT_SYMBOL_GPL(amvdec_src_change);
+diff --git a/drivers/staging/media/meson/vdec/vdec_helpers.h b/drivers/staging/media/meson/vdec/vdec_helpers.h
+index 4bf3e61d081b..1a711679d26a 100644
+--- a/drivers/staging/media/meson/vdec/vdec_helpers.h
++++ b/drivers/staging/media/meson/vdec/vdec_helpers.h
+@@ -27,9 +27,10 @@ void amvdec_clear_dos_bits(struct amvdec_core *core, u32 reg, u32 val);
+ u32 amvdec_read_parser(struct amvdec_core *core, u32 reg);
+ void amvdec_write_parser(struct amvdec_core *core, u32 reg, u32 val);
+
+-u32 amvdec_am21c_body_size(u32 width, u32 height);
+-u32 amvdec_am21c_head_size(u32 width, u32 height);
+-u32 amvdec_am21c_size(u32 width, u32 height);
++/* Helpers for the Amlogic compressed framebuffer format */
++u32 amvdec_amfbc_body_size(u32 width, u32 height, u32 is_10bit, u32 use_mmu);
++u32 amvdec_amfbc_head_size(u32 width, u32 height);
++u32 amvdec_amfbc_size(u32 width, u32 height, u32 is_10bit, u32 use_mmu);
+
+ /**
+ * amvdec_dst_buf_done_idx() - Signal that a buffer is done decoding
+@@ -77,9 +78,10 @@ void amvdec_set_par_from_dar(struct amvdec_session *sess,
+ * @width: picture width detected by the hardware
+ * @height: picture height detected by the hardware
+ * @dpb_size: Decoded Picture Buffer size (= amount of buffers for decoding)
++ * @bitdepth: Bit depth (usually 10 or 8) of the coded content
+ */
+ void amvdec_src_change(struct amvdec_session *sess, u32 width,
+- u32 height, u32 dpb_size);
++ u32 height, u32 dpb_size, u32 bitdepth);
+
+ /**
+ * amvdec_abort() - Abort the current decoding session
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,1609 @@
+From 9c91e0c4fb4deb050b4a8b4fc0b338c3145814b5 Mon Sep 17 00:00:00 2001
+From: benjamin545 <benjamin545@gmail.com>
+Date: Thu, 15 Jul 2021 17:08:42 -0400
+Subject: [PATCH 35/73] WIP: drivers: meson: vdec: add HEVC decode codec
+
+---
+ drivers/staging/media/meson/vdec/Makefile | 2 +-
+ drivers/staging/media/meson/vdec/codec_hevc.c | 1440 +++++++++++++++++
+ drivers/staging/media/meson/vdec/codec_hevc.h | 13 +
+ drivers/staging/media/meson/vdec/esparser.c | 2 +-
+ drivers/staging/media/meson/vdec/hevc_regs.h | 1 +
+ .../staging/media/meson/vdec/vdec_platform.c | 49 +
+ 6 files changed, 1505 insertions(+), 2 deletions(-)
+ create mode 100644 drivers/staging/media/meson/vdec/codec_hevc.c
+ create mode 100644 drivers/staging/media/meson/vdec/codec_hevc.h
+
+diff --git a/drivers/staging/media/meson/vdec/Makefile b/drivers/staging/media/meson/vdec/Makefile
+index 6e726af84ac9..16f848e456b9 100644
+--- a/drivers/staging/media/meson/vdec/Makefile
++++ b/drivers/staging/media/meson/vdec/Makefile
+@@ -3,6 +3,6 @@
+
+ meson-vdec-objs = esparser.o vdec.o vdec_helpers.o vdec_platform.o
+ meson-vdec-objs += vdec_1.o vdec_hevc.o
+-meson-vdec-objs += codec_mpeg12.o codec_h264.o codec_hevc_common.o codec_vp9.o
++meson-vdec-objs += codec_mpeg12.o codec_h264.o codec_hevc_common.o codec_vp9.o codec_hevc.o
+
+ obj-$(CONFIG_VIDEO_MESON_VDEC) += meson-vdec.o
+diff --git a/drivers/staging/media/meson/vdec/codec_hevc.c b/drivers/staging/media/meson/vdec/codec_hevc.c
+new file mode 100644
+index 000000000000..3a6fd04a2d33
+--- /dev/null
++++ b/drivers/staging/media/meson/vdec/codec_hevc.c
+@@ -0,0 +1,1440 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * Copyright (C) 2018 Maxime Jourdan <mjourdan@baylibre.com>
++ * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
++ */
++
++#include <media/v4l2-mem2mem.h>
++#include <media/videobuf2-dma-contig.h>
++
++#include "codec_hevc.h"
++#include "dos_regs.h"
++#include "hevc_regs.h"
++#include "vdec_helpers.h"
++#include "codec_hevc_common.h"
++
++/* HEVC reg mapping */
++#define HEVC_DEC_STATUS_REG HEVC_ASSIST_SCRATCH_0
++ #define HEVC_ACTION_DONE 0xff
++#define HEVC_RPM_BUFFER HEVC_ASSIST_SCRATCH_1
++#define HEVC_SHORT_TERM_RPS HEVC_ASSIST_SCRATCH_2
++#define HEVC_VPS_BUFFER HEVC_ASSIST_SCRATCH_3
++#define HEVC_SPS_BUFFER HEVC_ASSIST_SCRATCH_4
++#define HEVC_PPS_BUFFER HEVC_ASSIST_SCRATCH_5
++#define HEVC_SAO_UP HEVC_ASSIST_SCRATCH_6
++#define HEVC_STREAM_SWAP_BUFFER HEVC_ASSIST_SCRATCH_7
++#define H265_MMU_MAP_BUFFER HEVC_ASSIST_SCRATCH_7
++#define HEVC_STREAM_SWAP_BUFFER2 HEVC_ASSIST_SCRATCH_8
++#define HEVC_sao_mem_unit HEVC_ASSIST_SCRATCH_9
++#define HEVC_SAO_ABV HEVC_ASSIST_SCRATCH_A
++#define HEVC_sao_vb_size HEVC_ASSIST_SCRATCH_B
++#define HEVC_SAO_VB HEVC_ASSIST_SCRATCH_C
++#define HEVC_SCALELUT HEVC_ASSIST_SCRATCH_D
++#define HEVC_WAIT_FLAG HEVC_ASSIST_SCRATCH_E
++#define RPM_CMD_REG HEVC_ASSIST_SCRATCH_F
++#define LMEM_DUMP_ADR HEVC_ASSIST_SCRATCH_F
++#define DEBUG_REG1 HEVC_ASSIST_SCRATCH_G
++#define HEVC_DECODE_MODE2 HEVC_ASSIST_SCRATCH_H
++#define NAL_SEARCH_CTL HEVC_ASSIST_SCRATCH_I
++#define HEVC_DECODE_MODE HEVC_ASSIST_SCRATCH_J
++ #define DECODE_MODE_SINGLE 0
++#define DECODE_STOP_POS HEVC_ASSIST_SCRATCH_K
++#define HEVC_AUX_ADR HEVC_ASSIST_SCRATCH_L
++#define HEVC_AUX_DATA_SIZE HEVC_ASSIST_SCRATCH_M
++#define HEVC_DECODE_SIZE HEVC_ASSIST_SCRATCH_N
++
++#define AMRISC_MAIN_REQ 0x04
++
++/* HEVC Constants */
++#define MAX_REF_PIC_NUM 24
++#define MAX_REF_ACTIVE 16
++#define MAX_TILE_COL_NUM 10
++#define MAX_TILE_ROW_NUM 20
++#define MAX_SLICE_NUM 800
++#define INVALID_POC 0x80000000
++
++/* HEVC Workspace layout */
++#define MPRED_MV_BUF_SIZE 0x120000
++
++#define IPP_SIZE 0x4000
++#define SAO_ABV_SIZE 0x30000
++#define SAO_VB_SIZE 0x30000
++#define SH_TM_RPS_SIZE 0x800
++#define VPS_SIZE 0x800
++#define SPS_SIZE 0x800
++#define PPS_SIZE 0x2000
++#define SAO_UP_SIZE 0x2800
++#define SWAP_BUF_SIZE 0x800
++#define SWAP_BUF2_SIZE 0x800
++#define SCALELUT_SIZE 0x8000
++#define DBLK_PARA_SIZE 0x20000
++#define DBLK_DATA_SIZE 0x80000
++#define DBLK_DATA2_SIZE 0x80000
++#define MMU_VBH_SIZE 0x5000
++#define MPRED_ABV_SIZE 0x8000
++#define MPRED_MV_SIZE (MPRED_MV_BUF_SIZE * MAX_REF_PIC_NUM)
++#define RPM_BUF_SIZE 0x100
++#define LMEM_SIZE 0xA00
++
++#define IPP_OFFSET 0x00
++#define SAO_ABV_OFFSET (IPP_OFFSET + IPP_SIZE)
++#define SAO_VB_OFFSET (SAO_ABV_OFFSET + SAO_ABV_SIZE)
++#define SH_TM_RPS_OFFSET (SAO_VB_OFFSET + SAO_VB_SIZE)
++#define VPS_OFFSET (SH_TM_RPS_OFFSET + SH_TM_RPS_SIZE)
++#define SPS_OFFSET (VPS_OFFSET + VPS_SIZE)
++#define PPS_OFFSET (SPS_OFFSET + SPS_SIZE)
++#define SAO_UP_OFFSET (PPS_OFFSET + PPS_SIZE)
++#define SWAP_BUF_OFFSET (SAO_UP_OFFSET + SAO_UP_SIZE)
++#define SWAP_BUF2_OFFSET (SWAP_BUF_OFFSET + SWAP_BUF_SIZE)
++#define SCALELUT_OFFSET (SWAP_BUF2_OFFSET + SWAP_BUF2_SIZE)
++#define DBLK_PARA_OFFSET (SCALELUT_OFFSET + SCALELUT_SIZE)
++#define DBLK_DATA_OFFSET (DBLK_PARA_OFFSET + DBLK_PARA_SIZE)
++#define DBLK_DATA2_OFFSET (DBLK_DATA_OFFSET + DBLK_DATA_SIZE)
++#define MMU_VBH_OFFSET (DBLK_DATA2_OFFSET + DBLK_DATA2_SIZE)
++#define MPRED_ABV_OFFSET (MMU_VBH_OFFSET + MMU_VBH_SIZE)
++#define MPRED_MV_OFFSET (MPRED_ABV_OFFSET + MPRED_ABV_SIZE)
++#define RPM_OFFSET (MPRED_MV_OFFSET + MPRED_MV_SIZE)
++#define LMEM_OFFSET (RPM_OFFSET + RPM_BUF_SIZE)
++
++/* ISR decode status */
++#define HEVC_DEC_IDLE 0x0
++#define HEVC_NAL_UNIT_VPS 0x1
++#define HEVC_NAL_UNIT_SPS 0x2
++#define HEVC_NAL_UNIT_PPS 0x3
++#define HEVC_NAL_UNIT_CODED_SLICE_SEGMENT 0x4
++#define HEVC_CODED_SLICE_SEGMENT_DAT 0x5
++#define HEVC_SLICE_DECODING 0x6
++#define HEVC_NAL_UNIT_SEI 0x7
++#define HEVC_SLICE_SEGMENT_DONE 0x8
++#define HEVC_NAL_SEARCH_DONE 0x9
++#define HEVC_DECPIC_DATA_DONE 0xa
++#define HEVC_DECPIC_DATA_ERROR 0xb
++#define HEVC_SEI_DAT 0xc
++#define HEVC_SEI_DAT_DONE 0xd
++
++/* RPM misc_flag0 */
++#define PCM_LOOP_FILTER_DISABLED_FLAG_BIT 0
++#define PCM_ENABLE_FLAG_BIT 1
++#define LOOP_FILER_ACROSS_TILES_ENABLED_FLAG_BIT 2
++#define PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG_BIT 3
++#define DEBLOCKING_FILTER_OVERRIDE_ENABLED_FLAG_BIT 4
++#define PPS_DEBLOCKING_FILTER_DISABLED_FLAG_BIT 5
++#define DEBLOCKING_FILTER_OVERRIDE_FLAG_BIT 6
++#define SLICE_DEBLOCKING_FILTER_DISABLED_FLAG_BIT 7
++#define SLICE_SAO_LUMA_FLAG_BIT 8
++#define SLICE_SAO_CHROMA_FLAG_BIT 9
++#define SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG_BIT 10
++
++/* Constants for HEVC_MPRED_CTRL1 */
++#define AMVP_MAX_NUM_CANDS_MEM 3
++#define AMVP_MAX_NUM_CANDS 2
++#define NUM_CHROMA_MODE 5
++#define DM_CHROMA_IDX 36
++
++/* Buffer sizes */
++#define SIZE_WORKSPACE ALIGN(LMEM_OFFSET + LMEM_SIZE, 64 * SZ_1K)
++#define SIZE_AUX (SZ_1K * 16)
++#define SIZE_FRAME_MMU (0x1200 * 4)
++#define RPM_SIZE 0x80
++#define RPS_USED_BIT 14
++
++/* Data received from the HW in this form, do not rearrange */
++union rpm_param {
++ struct {
++ u16 data[RPM_SIZE];
++ } l;
++ struct {
++ u16 CUR_RPS[MAX_REF_ACTIVE];
++ u16 num_ref_idx_l0_active;
++ u16 num_ref_idx_l1_active;
++ u16 slice_type;
++ u16 slice_temporal_mvp_enable_flag;
++ u16 dependent_slice_segment_flag;
++ u16 slice_segment_address;
++ u16 num_title_rows_minus1;
++ u16 pic_width_in_luma_samples;
++ u16 pic_height_in_luma_samples;
++ u16 log2_min_coding_block_size_minus3;
++ u16 log2_diff_max_min_coding_block_size;
++ u16 log2_max_pic_order_cnt_lsb_minus4;
++ u16 POClsb;
++ u16 collocated_from_l0_flag;
++ u16 collocated_ref_idx;
++ u16 log2_parallel_merge_level;
++ u16 five_minus_max_num_merge_cand;
++ u16 sps_num_reorder_pics_0;
++ u16 modification_flag;
++ u16 tiles_flags;
++ u16 num_tile_columns_minus1;
++ u16 num_tile_rows_minus1;
++ u16 tile_width[8];
++ u16 tile_height[8];
++ u16 misc_flag0;
++ u16 pps_beta_offset_div2;
++ u16 pps_tc_offset_div2;
++ u16 slice_beta_offset_div2;
++ u16 slice_tc_offset_div2;
++ u16 pps_cb_qp_offset;
++ u16 pps_cr_qp_offset;
++ u16 first_slice_segment_in_pic_flag;
++ u16 m_temporalId;
++ u16 m_nalUnitType;
++ u16 vui_num_units_in_tick_hi;
++ u16 vui_num_units_in_tick_lo;
++ u16 vui_time_scale_hi;
++ u16 vui_time_scale_lo;
++ u16 bit_depth;
++ u16 profile_etc;
++ u16 sei_frame_field_info;
++ u16 video_signal_type;
++ u16 modification_list[0x20];
++ u16 conformance_window_flag;
++ u16 conf_win_left_offset;
++ u16 conf_win_right_offset;
++ u16 conf_win_top_offset;
++ u16 conf_win_bottom_offset;
++ u16 chroma_format_idc;
++ u16 color_description;
++ u16 aspect_ratio_idc;
++ u16 sar_width;
++ u16 sar_height;
++ } p;
++};
++
++enum nal_unit_type {
++ NAL_UNIT_CODED_SLICE_BLA = 16,
++ NAL_UNIT_CODED_SLICE_BLANT = 17,
++ NAL_UNIT_CODED_SLICE_BLA_N_LP = 18,
++ NAL_UNIT_CODED_SLICE_IDR = 19,
++ NAL_UNIT_CODED_SLICE_IDR_N_LP = 20,
++};
++
++enum slice_type {
++ B_SLICE = 0,
++ P_SLICE = 1,
++ I_SLICE = 2,
++};
++
++/* A frame being decoded */
++struct hevc_frame {
++ struct list_head list;
++ struct vb2_v4l2_buffer *vbuf;
++ u32 offset;
++ u32 poc;
++
++ int referenced;
++ u32 num_reorder_pic;
++
++ u32 cur_slice_idx;
++ u32 cur_slice_type;
++
++ /* 2 lists (L0/L1) ; 800 slices ; 16 refs */
++ u32 ref_poc_list[2][MAX_SLICE_NUM][MAX_REF_ACTIVE];
++ u32 ref_num[2];
++};
++
++struct codec_hevc {
++ struct mutex lock;
++
++ /* Common part of the HEVC decoder */
++ struct codec_hevc_common common;
++
++ /* Buffer for the HEVC Workspace */
++ void *workspace_vaddr;
++ dma_addr_t workspace_paddr;
++
++ /* AUX buffer */
++ void *aux_vaddr;
++ dma_addr_t aux_paddr;
++
++ /* Contains many information parsed from the bitstream */
++ union rpm_param rpm_param;
++
++ /* Information computed from the RPM */
++ u32 lcu_size; // Largest Coding Unit
++ u32 lcu_x_num;
++ u32 lcu_y_num;
++ u32 lcu_total;
++
++ /* Current Frame being handled */
++ struct hevc_frame *cur_frame;
++ u32 curr_poc;
++ /* Collocated Reference Picture */
++ struct hevc_frame *col_frame;
++ u32 col_poc;
++
++ /* All ref frames used by the HW at a given time */
++ struct list_head ref_frames_list;
++ u32 frames_num;
++
++ /* Coded resolution reported by the hardware */
++ u32 width, height;
++ /* Resolution minus the conformance window offsets */
++ u32 dst_width, dst_height;
++
++ u32 prev_tid0_poc;
++ u32 slice_segment_addr;
++ u32 slice_addr;
++ u32 ldc_flag;
++
++ /* Whether we detected the bitstream as 10-bit */
++ int is_10bit;
++};
++
++static u32 codec_hevc_num_pending_bufs(struct amvdec_session *sess)
++{
++ struct codec_hevc *hevc;
++ u32 ret;
++
++ hevc = sess->priv;
++ if (!hevc)
++ return 0;
++
++ mutex_lock(&hevc->lock);
++ ret = hevc->frames_num;
++ mutex_unlock(&hevc->lock);
++
++ return ret;
++}
++
++/* Update the L0 and L1 reference lists for a given frame */
++static void codec_hevc_update_frame_refs(struct amvdec_session *sess,
++ struct hevc_frame *frame)
++{
++ struct codec_hevc *hevc = sess->priv;
++ union rpm_param *params = &hevc->rpm_param;
++ int num_ref_idx_l0_active =
++ (params->p.num_ref_idx_l0_active > MAX_REF_ACTIVE) ?
++ MAX_REF_ACTIVE : params->p.num_ref_idx_l0_active;
++ int num_ref_idx_l1_active =
++ (params->p.num_ref_idx_l1_active > MAX_REF_ACTIVE) ?
++ MAX_REF_ACTIVE : params->p.num_ref_idx_l1_active;
++ int ref_picset0[MAX_REF_ACTIVE] = { 0 };
++ int ref_picset1[MAX_REF_ACTIVE] = { 0 };
++ u16 *mod_list = params->p.modification_list;
++ int num_neg = 0;
++ int num_pos = 0;
++ int total_num;
++ int i;
++
++ for (i = 0; i < MAX_REF_ACTIVE; i++) {
++ frame->ref_poc_list[0][frame->cur_slice_idx][i] = 0;
++ frame->ref_poc_list[1][frame->cur_slice_idx][i] = 0;
++ }
++
++ for (i = 0; i < MAX_REF_ACTIVE; i++) {
++ u16 cur_rps = params->p.CUR_RPS[i];
++ int delt = cur_rps & ((1 << (RPS_USED_BIT - 1)) - 1);
++
++ if (cur_rps & 0x8000)
++ break;
++
++ if (!((cur_rps >> RPS_USED_BIT) & 1))
++ continue;
++
++ if ((cur_rps >> (RPS_USED_BIT - 1)) & 1) {
++ ref_picset0[num_neg] =
++ frame->poc - ((1 << (RPS_USED_BIT - 1)) - delt);
++ num_neg++;
++ } else {
++ ref_picset1[num_pos] = frame->poc + delt;
++ num_pos++;
++ }
++ }
++
++ total_num = num_neg + num_pos;
++
++ if (total_num <= 0)
++ goto end;
++
++ for (i = 0; i < num_ref_idx_l0_active; i++) {
++ int cidx;
++ if (params->p.modification_flag & 0x1)
++ cidx = mod_list[i];
++ else
++ cidx = i % total_num;
++
++ frame->ref_poc_list[0][frame->cur_slice_idx][i] =
++ cidx >= num_neg ? ref_picset1[cidx - num_neg] :
++ ref_picset0[cidx];
++ }
++
++ if (params->p.slice_type != B_SLICE)
++ goto end;
++
++ if (params->p.modification_flag & 0x2) {
++ for (i = 0; i < num_ref_idx_l1_active; i++) {
++ int cidx;
++ if (params->p.modification_flag & 0x1)
++ cidx = mod_list[num_ref_idx_l0_active + i];
++ else
++ cidx = mod_list[i];
++
++ frame->ref_poc_list[1][frame->cur_slice_idx][i] =
++ (cidx >= num_pos) ? ref_picset0[cidx - num_pos]
++ : ref_picset1[cidx];
++ }
++ } else {
++ for (i = 0; i < num_ref_idx_l1_active; i++) {
++ int cidx = i % total_num;
++ frame->ref_poc_list[1][frame->cur_slice_idx][i] =
++ cidx >= num_pos ? ref_picset0[cidx - num_pos] :
++ ref_picset1[cidx];
++ }
++ }
++
++end:
++ frame->ref_num[0] = num_ref_idx_l0_active;
++ frame->ref_num[1] = num_ref_idx_l1_active;
++
++ dev_dbg(sess->core->dev,
++ "Frame %u; slice %u; slice_type %u; num_l0 %u; num_l1 %u\n",
++ frame->poc, frame->cur_slice_idx, params->p.slice_type,
++ frame->ref_num[0], frame->ref_num[1]);
++}
++
++static void codec_hevc_update_ldc_flag(struct codec_hevc *hevc)
++{
++ struct hevc_frame *frame = hevc->cur_frame;
++ u32 slice_type = frame->cur_slice_type;
++ u32 slice_idx = frame->cur_slice_idx;
++ int i;
++
++ hevc->ldc_flag = 0;
++
++ if (slice_type == I_SLICE)
++ return;
++
++ hevc->ldc_flag = 1;
++ for (i = 0; (i < frame->ref_num[0]) && hevc->ldc_flag; i++) {
++ if (frame->ref_poc_list[0][slice_idx][i] > frame->poc) {
++ hevc->ldc_flag = 0;
++ break;
++ }
++ }
++
++ if (slice_type == P_SLICE)
++ return;
++
++ for (i = 0; (i < frame->ref_num[1]) && hevc->ldc_flag; i++) {
++ if (frame->ref_poc_list[1][slice_idx][i] > frame->poc) {
++ hevc->ldc_flag = 0;
++ break;
++ }
++ }
++}
++
++/* Tag "old" frames that are no longer referenced */
++static void codec_hevc_update_referenced(struct codec_hevc *hevc)
++{
++ union rpm_param *param = &hevc->rpm_param;
++ struct hevc_frame *frame;
++ int i;
++ u32 curr_poc = hevc->curr_poc;
++
++ list_for_each_entry(frame, &hevc->ref_frames_list, list) {
++ int is_referenced = 0;
++ u32 poc_tmp;
++
++ if (!frame->referenced)
++ continue;
++
++ for (i = 0; i < MAX_REF_ACTIVE; i++) {
++ int delt;
++ if (param->p.CUR_RPS[i] & 0x8000)
++ break;
++
++ delt = param->p.CUR_RPS[i] &
++ ((1 << (RPS_USED_BIT - 1)) - 1);
++ if (param->p.CUR_RPS[i] & (1 << (RPS_USED_BIT - 1))) {
++ poc_tmp = curr_poc -
++ ((1 << (RPS_USED_BIT - 1)) - delt);
++ } else
++ poc_tmp = curr_poc + delt;
++ if (poc_tmp == frame->poc) {
++ is_referenced = 1;
++ break;
++ }
++ }
++
++ frame->referenced = is_referenced;
++ }
++}
++
++static struct hevc_frame *
++codec_hevc_get_lowest_poc_frame(struct codec_hevc *hevc)
++{
++ struct hevc_frame *tmp, *ret = NULL;
++ u32 poc = INT_MAX;
++
++ list_for_each_entry(tmp, &hevc->ref_frames_list, list) {
++ if (tmp->poc < poc) {
++ ret = tmp;
++ poc = tmp->poc;
++ }
++ }
++
++ return ret;
++}
++
++/* Try to output as many frames as possible */
++static void codec_hevc_output_frames(struct amvdec_session *sess)
++{
++ struct hevc_frame *tmp;
++ struct codec_hevc *hevc = sess->priv;
++
++ while ((tmp = codec_hevc_get_lowest_poc_frame(hevc))) {
++ if (hevc->curr_poc &&
++ (tmp->referenced ||
++ tmp->num_reorder_pic >= hevc->frames_num))
++ break;
++
++ dev_dbg(sess->core->dev, "DONE frame poc %u; vbuf %u\n",
++ tmp->poc, tmp->vbuf->vb2_buf.index);
++ amvdec_dst_buf_done_offset(sess, tmp->vbuf, tmp->offset,
++ V4L2_FIELD_NONE, false);
++ list_del(&tmp->list);
++ kfree(tmp);
++ hevc->frames_num--;
++ }
++}
++
++
++static int
++codec_hevc_setup_workspace(struct amvdec_session *sess,
++ struct codec_hevc *hevc)
++{
++ struct amvdec_core *core = sess->core;
++ u32 revision = core->platform->revision;
++ dma_addr_t wkaddr;
++
++ /* Allocate some memory for the HEVC decoder's state */
++ hevc->workspace_vaddr = dma_alloc_coherent(core->dev, SIZE_WORKSPACE,
++ &wkaddr, GFP_KERNEL);
++ if (!hevc->workspace_vaddr)
++ return -ENOMEM;
++
++ hevc->workspace_paddr = wkaddr;
++
++ amvdec_write_dos(core, HEVCD_IPP_LINEBUFF_BASE, wkaddr + IPP_OFFSET);
++ amvdec_write_dos(core, HEVC_RPM_BUFFER, wkaddr + RPM_OFFSET);
++ amvdec_write_dos(core, HEVC_SHORT_TERM_RPS, wkaddr + SH_TM_RPS_OFFSET);
++ amvdec_write_dos(core, HEVC_VPS_BUFFER, wkaddr + VPS_OFFSET);
++ amvdec_write_dos(core, HEVC_SPS_BUFFER, wkaddr + SPS_OFFSET);
++ amvdec_write_dos(core, HEVC_PPS_BUFFER, wkaddr + PPS_OFFSET);
++ amvdec_write_dos(core, HEVC_SAO_UP, wkaddr + SAO_UP_OFFSET);
++
++ if (codec_hevc_use_mmu(revision, sess->pixfmt_cap, hevc->is_10bit)) {
++ amvdec_write_dos(core, HEVC_SAO_MMU_VH0_ADDR,
++ wkaddr + MMU_VBH_OFFSET);
++ amvdec_write_dos(core, HEVC_SAO_MMU_VH1_ADDR,
++ wkaddr + MMU_VBH_OFFSET + (MMU_VBH_SIZE / 2));
++
++ if (revision >= VDEC_REVISION_G12A)
++ amvdec_write_dos(core, HEVC_ASSIST_MMU_MAP_ADDR,
++ hevc->common.mmu_map_paddr);
++ else
++ amvdec_write_dos(core, H265_MMU_MAP_BUFFER,
++ hevc->common.mmu_map_paddr);
++ } else if (revision < VDEC_REVISION_G12A) {
++ amvdec_write_dos(core, HEVC_STREAM_SWAP_BUFFER,
++ wkaddr + SWAP_BUF_OFFSET);
++ amvdec_write_dos(core, HEVC_STREAM_SWAP_BUFFER2,
++ wkaddr + SWAP_BUF2_OFFSET);
++ }
++
++ amvdec_write_dos(core, HEVC_SCALELUT, wkaddr + SCALELUT_OFFSET);
++ amvdec_write_dos(core, HEVC_DBLK_CFG4, wkaddr + DBLK_PARA_OFFSET);
++ amvdec_write_dos(core, HEVC_DBLK_CFG5, wkaddr + DBLK_DATA_OFFSET);
++ if (revision >= VDEC_REVISION_G12A)
++ amvdec_write_dos(core, HEVC_DBLK_CFGE,
++ wkaddr + DBLK_DATA2_OFFSET);
++
++ amvdec_write_dos(core, LMEM_DUMP_ADR, wkaddr + LMEM_OFFSET);
++
++ return 0;
++}
++
++static int codec_hevc_start(struct amvdec_session *sess)
++{
++ struct amvdec_core *core = sess->core;
++ struct codec_hevc *hevc;
++ u32 val;
++ int i;
++ int ret;
++
++ hevc = kzalloc(sizeof(*hevc), GFP_KERNEL);
++ if (!hevc)
++ return -ENOMEM;
++
++ INIT_LIST_HEAD(&hevc->ref_frames_list);
++ hevc->curr_poc = INVALID_POC;
++
++ ret = codec_hevc_setup_workspace(sess, hevc);
++ if (ret)
++ goto free_hevc;
++
++ val = BIT(0); /* stream_fetch_enable */
++ if (core->platform->revision >= VDEC_REVISION_G12A)
++ val |= (0xf << 25); /* arwlen_axi_max */
++ amvdec_write_dos_bits(core, HEVC_STREAM_CONTROL, val);
++
++ val = amvdec_read_dos(core, HEVC_PARSER_INT_CONTROL) & 0x03ffffff;
++ val |= (3 << 29) | BIT(27) | BIT(24) | BIT(22) | BIT(7) | BIT(4) |
++ BIT(0);
++ amvdec_write_dos(core, HEVC_PARSER_INT_CONTROL, val);
++ amvdec_write_dos_bits(core, HEVC_SHIFT_STATUS, BIT(1) | BIT(0));
++ amvdec_write_dos(core, HEVC_SHIFT_CONTROL,
++ (3 << 6) | BIT(5) | BIT(2) | BIT(0));
++ amvdec_write_dos(core, HEVC_CABAC_CONTROL, 1);
++ amvdec_write_dos(core, HEVC_PARSER_CORE_CONTROL, 1);
++ amvdec_write_dos(core, HEVC_DEC_STATUS_REG, 0);
++
++ amvdec_write_dos(core, HEVC_IQIT_SCALELUT_WR_ADDR, 0);
++ for (i = 0; i < 1024; ++i)
++ amvdec_write_dos(core, HEVC_IQIT_SCALELUT_DATA, 0);
++
++ amvdec_write_dos(core, HEVC_DECODE_SIZE, 0);
++
++ amvdec_write_dos(core, HEVC_PARSER_CMD_WRITE, BIT(16));
++ for (i = 0; i < ARRAY_SIZE(vdec_hevc_parser_cmd); ++i)
++ amvdec_write_dos(core, HEVC_PARSER_CMD_WRITE,
++ vdec_hevc_parser_cmd[i]);
++
++ amvdec_write_dos(core, HEVC_PARSER_CMD_SKIP_0, PARSER_CMD_SKIP_CFG_0);
++ amvdec_write_dos(core, HEVC_PARSER_CMD_SKIP_1, PARSER_CMD_SKIP_CFG_1);
++ amvdec_write_dos(core, HEVC_PARSER_CMD_SKIP_2, PARSER_CMD_SKIP_CFG_2);
++ amvdec_write_dos(core, HEVC_PARSER_IF_CONTROL,
++ BIT(5) | BIT(2) | BIT(0));
++
++ amvdec_write_dos(core, HEVCD_IPP_TOP_CNTL, BIT(0));
++ amvdec_write_dos(core, HEVCD_IPP_TOP_CNTL, BIT(1));
++
++ amvdec_write_dos(core, HEVC_WAIT_FLAG, 1);
++
++ /* clear mailbox interrupt */
++ amvdec_write_dos(core, HEVC_ASSIST_MBOX1_CLR_REG, 1);
++ /* enable mailbox interrupt */
++ amvdec_write_dos(core, HEVC_ASSIST_MBOX1_MASK, 1);
++ /* disable PSCALE for hardware sharing */
++ amvdec_write_dos(core, HEVC_PSCALE_CTRL, 0);
++ /* Let the uCode do all the parsing */
++ amvdec_write_dos(core, NAL_SEARCH_CTL, 0xc);
++
++ amvdec_write_dos(core, DECODE_STOP_POS, 0);
++ amvdec_write_dos(core, HEVC_DECODE_MODE, DECODE_MODE_SINGLE);
++ amvdec_write_dos(core, HEVC_DECODE_MODE2, 0);
++
++ /* AUX buffers */
++ hevc->aux_vaddr = dma_alloc_coherent(core->dev, SIZE_AUX,
++ &hevc->aux_paddr, GFP_KERNEL);
++ if (!hevc->aux_vaddr) {
++ dev_err(core->dev, "Failed to request HEVC AUX\n");
++ ret = -ENOMEM;
++ goto free_hevc;
++ }
++
++ amvdec_write_dos(core, HEVC_AUX_ADR, hevc->aux_paddr);
++ amvdec_write_dos(core, HEVC_AUX_DATA_SIZE,
++ (((SIZE_AUX) >> 4) << 16) | 0);
++ mutex_init(&hevc->lock);
++ sess->priv = hevc;
++
++ return 0;
++
++free_hevc:
++ kfree(hevc);
++ return ret;
++}
++
++static void codec_hevc_flush_output(struct amvdec_session *sess)
++{
++ struct codec_hevc *hevc = sess->priv;
++ struct hevc_frame *tmp;
++
++ while (!list_empty(&hevc->ref_frames_list)) {
++ tmp = codec_hevc_get_lowest_poc_frame(hevc);
++ amvdec_dst_buf_done(sess, tmp->vbuf, V4L2_FIELD_NONE);
++ list_del(&tmp->list);
++ kfree(tmp);
++ hevc->frames_num--;
++ }
++}
++
++static int codec_hevc_stop(struct amvdec_session *sess)
++{
++ struct codec_hevc *hevc = sess->priv;
++ struct amvdec_core *core = sess->core;
++
++ mutex_lock(&hevc->lock);
++ codec_hevc_flush_output(sess);
++
++ if (hevc->workspace_vaddr)
++ dma_free_coherent(core->dev, SIZE_WORKSPACE,
++ hevc->workspace_vaddr,
++ hevc->workspace_paddr);
++
++ if (hevc->aux_vaddr)
++ dma_free_coherent(core->dev, SIZE_AUX,
++ hevc->aux_vaddr, hevc->aux_paddr);
++
++ codec_hevc_free_fbc_buffers(sess, &hevc->common);
++ mutex_unlock(&hevc->lock);
++ mutex_destroy(&hevc->lock);
++
++ return 0;
++}
++
++static struct hevc_frame *
++codec_hevc_get_frame_by_poc(struct codec_hevc *hevc, u32 poc)
++{
++ struct hevc_frame *tmp;
++
++ list_for_each_entry(tmp, &hevc->ref_frames_list, list) {
++ if (tmp->poc == poc)
++ return tmp;
++ }
++
++ return NULL;
++}
++
++static struct hevc_frame *
++codec_hevc_prepare_new_frame(struct amvdec_session *sess)
++{
++ struct amvdec_core *core = sess->core;
++ struct hevc_frame *new_frame = NULL;
++ struct codec_hevc *hevc = sess->priv;
++ struct vb2_v4l2_buffer *vbuf;
++ union rpm_param *params = &hevc->rpm_param;
++
++ new_frame = kzalloc(sizeof(*new_frame), GFP_KERNEL);
++ if (!new_frame)
++ return NULL;
++
++ vbuf = v4l2_m2m_dst_buf_remove(sess->m2m_ctx);
++ if (!vbuf) {
++ dev_err(sess->core->dev, "No dst buffer available\n");
++ return NULL;
++ }
++
++ new_frame->vbuf = vbuf;
++ new_frame->referenced = 1;
++ new_frame->poc = hevc->curr_poc;
++ new_frame->cur_slice_type = params->p.slice_type;
++ new_frame->num_reorder_pic = params->p.sps_num_reorder_pics_0;
++ new_frame->offset = amvdec_read_dos(core, HEVC_SHIFT_BYTE_COUNT);
++
++ list_add_tail(&new_frame->list, &hevc->ref_frames_list);
++ hevc->frames_num++;
++
++ return new_frame;
++}
++
++static void
++codec_hevc_set_sao(struct amvdec_session *sess, struct hevc_frame *frame)
++{
++ struct amvdec_core *core = sess->core;
++ struct codec_hevc *hevc = sess->priv;
++ struct vb2_buffer *vb = &frame->vbuf->vb2_buf;
++ union rpm_param *param = &hevc->rpm_param;
++ u32 pic_height_cu =
++ (hevc->height + hevc->lcu_size - 1) / hevc->lcu_size;
++ u32 sao_mem_unit = (hevc->lcu_size == 16 ? 9 :
++ hevc->lcu_size == 32 ? 14 : 24) << 4;
++ u32 sao_vb_size = (sao_mem_unit + (2 << 4)) * pic_height_cu;
++ u32 misc_flag0 = param->p.misc_flag0;
++ dma_addr_t buf_y_paddr;
++ dma_addr_t buf_u_v_paddr;
++ u32 slice_deblocking_filter_disabled_flag;
++ u32 val, val_2;
++
++ val = (amvdec_read_dos(core, HEVC_SAO_CTRL0) & ~0xf) |
++ ilog2(hevc->lcu_size);
++ amvdec_write_dos(core, HEVC_SAO_CTRL0, val);
++
++ amvdec_write_dos(core, HEVC_SAO_PIC_SIZE,
++ hevc->width | (hevc->height << 16));
++ amvdec_write_dos(core, HEVC_SAO_PIC_SIZE_LCU,
++ (hevc->lcu_x_num - 1) | (hevc->lcu_y_num - 1) << 16);
++
++ if (codec_hevc_use_downsample(sess->pixfmt_cap, hevc->is_10bit) ||
++ codec_hevc_use_mmu(core->platform->revision, sess->pixfmt_cap,
++ hevc->is_10bit))
++ buf_y_paddr =
++ hevc->common.fbc_buffer_paddr[vb->index];
++ else
++ buf_y_paddr =
++ vb2_dma_contig_plane_dma_addr(vb, 0);
++
++ if (codec_hevc_use_fbc(sess->pixfmt_cap, hevc->is_10bit)) {
++ val = amvdec_read_dos(core, HEVC_SAO_CTRL5) & ~0xff0000;
++ amvdec_write_dos(core, HEVC_SAO_CTRL5, val);
++ amvdec_write_dos(core, HEVC_CM_BODY_START_ADDR, buf_y_paddr);
++ }
++
++ if (sess->pixfmt_cap == V4L2_PIX_FMT_NV12M) {
++ buf_y_paddr =
++ vb2_dma_contig_plane_dma_addr(vb, 0);
++ buf_u_v_paddr =
++ vb2_dma_contig_plane_dma_addr(vb, 1);
++ amvdec_write_dos(core, HEVC_SAO_Y_START_ADDR, buf_y_paddr);
++ amvdec_write_dos(core, HEVC_SAO_C_START_ADDR, buf_u_v_paddr);
++ amvdec_write_dos(core, HEVC_SAO_Y_WPTR, buf_y_paddr);
++ amvdec_write_dos(core, HEVC_SAO_C_WPTR, buf_u_v_paddr);
++ }
++
++ if (codec_hevc_use_mmu(core->platform->revision, sess->pixfmt_cap,
++ hevc->is_10bit)) {
++ dma_addr_t header_adr = vb2_dma_contig_plane_dma_addr(vb, 0);
++ if (codec_hevc_use_downsample(sess->pixfmt_cap, hevc->is_10bit))
++ header_adr = hevc->common.mmu_header_paddr[vb->index];
++ amvdec_write_dos(core, HEVC_CM_HEADER_START_ADDR, header_adr);
++ /* use HEVC_CM_HEADER_START_ADDR */
++ amvdec_write_dos_bits(core, HEVC_SAO_CTRL5, BIT(10));
++ amvdec_write_dos_bits(core, HEVC_SAO_CTRL9, BIT(0));
++ }
++
++ amvdec_write_dos(core, HEVC_SAO_Y_LENGTH,
++ amvdec_get_output_size(sess));
++ amvdec_write_dos(core, HEVC_SAO_C_LENGTH,
++ (amvdec_get_output_size(sess) / 2));
++
++ if (frame->cur_slice_idx == 0) {
++ if (core->platform->revision >= VDEC_REVISION_G12A) {
++ if (core->platform->revision >= VDEC_REVISION_SM1)
++ val = 0xfc << 8;
++ else
++ val = 0x54 << 8;
++
++ /* enable first, compressed write */
++ if (codec_hevc_use_fbc(sess->pixfmt_cap,
++ hevc->is_10bit))
++ val |= BIT(8);
++
++ /* enable second, uncompressed write */
++ if (sess->pixfmt_cap == V4L2_PIX_FMT_NV12M)
++ val |= BIT(9);
++
++ /* dblk pipeline mode=1 for performance */
++ if (hevc->width >= 1280)
++ val |= BIT(4);
++
++ amvdec_write_dos(core, HEVC_DBLK_CFGB, val);
++ amvdec_write_dos(core, HEVC_DBLK_STS1 + 16, BIT(28));
++ }
++
++ amvdec_write_dos(core, HEVC_DBLK_CFG2,
++ hevc->width | (hevc->height << 16));
++
++ val = 0;
++ if ((misc_flag0 >> PCM_ENABLE_FLAG_BIT) & 0x1)
++ val |= ((misc_flag0 >>
++ PCM_LOOP_FILTER_DISABLED_FLAG_BIT) & 0x1) << 3;
++
++ val |= (param->p.pps_cb_qp_offset & 0x1f) << 4;
++ val |= (param->p.pps_cr_qp_offset & 0x1f) << 9;
++ val |= (hevc->lcu_size == 64) ? 0 :
++ ((hevc->lcu_size == 32) ? 1 : 2);
++ amvdec_write_dos(core, HEVC_DBLK_CFG1, val);
++ }
++
++ val = amvdec_read_dos(core, HEVC_SAO_CTRL1) & ~0x3ff3;
++ val |= 0xff0; /* Set endianness for 2-bytes swaps (nv12) */
++ if (core->platform->revision < VDEC_REVISION_G12A) {
++ if (!codec_hevc_use_fbc(sess->pixfmt_cap, hevc->is_10bit))
++ val |= BIT(0); /* disable cm compression */
++ /* TOFIX: Handle Amlogic Framebuffer compression */
++ }
++
++ amvdec_write_dos(core, HEVC_SAO_CTRL1, val);
++
++ if (!codec_hevc_use_fbc(sess->pixfmt_cap, hevc->is_10bit)) {
++ /* no downscale for NV12 */
++ val = amvdec_read_dos(core, HEVC_SAO_CTRL5) & ~0xff0000;
++ amvdec_write_dos(core, HEVC_SAO_CTRL5, val);
++ }
++
++ val = amvdec_read_dos(core, HEVCD_IPP_AXIIF_CONFIG) & ~0x30;
++ val |= 0xf;
++ amvdec_write_dos(core, HEVCD_IPP_AXIIF_CONFIG, val);
++
++ val = 0;
++ val_2 = amvdec_read_dos(core, HEVC_SAO_CTRL0);
++ val_2 &= (~0x300);
++
++ slice_deblocking_filter_disabled_flag = (misc_flag0 >>
++ SLICE_DEBLOCKING_FILTER_DISABLED_FLAG_BIT) & 0x1;
++ if ((misc_flag0 & (1 << DEBLOCKING_FILTER_OVERRIDE_ENABLED_FLAG_BIT))
++ && (misc_flag0 & (1 << DEBLOCKING_FILTER_OVERRIDE_FLAG_BIT))) {
++ val |= slice_deblocking_filter_disabled_flag << 2;
++
++ if (!slice_deblocking_filter_disabled_flag) {
++ val |= (param->p.slice_beta_offset_div2 & 0xf) << 3;
++ val |= (param->p.slice_tc_offset_div2 & 0xf) << 7;
++ }
++ } else {
++ val |=
++ ((misc_flag0 >>
++ PPS_DEBLOCKING_FILTER_DISABLED_FLAG_BIT) & 0x1) << 2;
++
++ if (((misc_flag0 >> PPS_DEBLOCKING_FILTER_DISABLED_FLAG_BIT) &
++ 0x1) == 0) {
++ val |= (param->p.pps_beta_offset_div2 & 0xf) << 3;
++ val |= (param->p.pps_tc_offset_div2 & 0xf) << 7;
++ }
++ }
++ if ((misc_flag0 & (1 << PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG_BIT))
++ && ((misc_flag0 & (1 << SLICE_SAO_LUMA_FLAG_BIT))
++ || (misc_flag0 & (1 << SLICE_SAO_CHROMA_FLAG_BIT))
++ || (!slice_deblocking_filter_disabled_flag))) {
++ val |=
++ ((misc_flag0 >>
++ SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG_BIT)
++ & 0x1) << 1;
++ val_2 |=
++ ((misc_flag0 >>
++ SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG_BIT)
++ & 0x1) << 9;
++ } else {
++ val |=
++ ((misc_flag0 >>
++ PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG_BIT)
++ & 0x1) << 1;
++ val_2 |=
++ ((misc_flag0 >>
++ PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG_BIT)
++ & 0x1) << 9;
++ }
++
++ amvdec_write_dos(core, HEVC_DBLK_CFG9, val);
++ amvdec_write_dos(core, HEVC_SAO_CTRL0, val_2);
++
++ amvdec_write_dos(core, HEVC_sao_mem_unit, sao_mem_unit);
++ amvdec_write_dos(core, HEVC_SAO_ABV,
++ hevc->workspace_paddr + SAO_ABV_OFFSET);
++ amvdec_write_dos(core, HEVC_sao_vb_size, sao_vb_size);
++ amvdec_write_dos(core, HEVC_SAO_VB,
++ hevc->workspace_paddr + SAO_VB_OFFSET);
++}
++
++static dma_addr_t codec_hevc_get_frame_mv_paddr(struct codec_hevc *hevc,
++ struct hevc_frame *frame)
++{
++ return hevc->workspace_paddr + MPRED_MV_OFFSET +
++ (frame->vbuf->vb2_buf.index * MPRED_MV_BUF_SIZE);
++}
++
++static void
++codec_hevc_set_mpred_ctrl(struct amvdec_core *core, struct codec_hevc *hevc)
++{
++ union rpm_param *param = &hevc->rpm_param;
++ u32 slice_type = param->p.slice_type;
++ u32 lcu_size_log2 = ilog2(hevc->lcu_size);
++ u32 val;
++
++ val = slice_type |
++ MPRED_CTRL0_ABOVE_EN |
++ MPRED_CTRL0_MV_WR_EN |
++ MPRED_CTRL0_BUF_LINEAR |
++ (lcu_size_log2 << 16) |
++ (3 << 20) | /* cu_size_log2 */
++ (param->p.log2_parallel_merge_level << 24);
++
++ if (slice_type != I_SLICE)
++ val |= MPRED_CTRL0_MV_RD_EN;
++
++ if (param->p.collocated_from_l0_flag)
++ val |= MPRED_CTRL0_COL_FROM_L0;
++
++ if (param->p.slice_temporal_mvp_enable_flag)
++ val |= MPRED_CTRL0_TMVP;
++
++ if (hevc->ldc_flag)
++ val |= MPRED_CTRL0_LDC;
++
++ if (param->p.dependent_slice_segment_flag)
++ val |= MPRED_CTRL0_NEW_SLI_SEG;
++
++ if (param->p.slice_segment_address == 0)
++ val |= MPRED_CTRL0_NEW_PIC |
++ MPRED_CTRL0_NEW_TILE;
++
++ amvdec_write_dos(core, HEVC_MPRED_CTRL0, val);
++
++ val = (5 - param->p.five_minus_max_num_merge_cand) |
++ (AMVP_MAX_NUM_CANDS << 4) |
++ (AMVP_MAX_NUM_CANDS_MEM << 8) |
++ (NUM_CHROMA_MODE << 12) |
++ (DM_CHROMA_IDX << 16);
++ amvdec_write_dos(core, HEVC_MPRED_CTRL1, val);
++}
++
++static void codec_hevc_set_mpred_mv(struct amvdec_core *core,
++ struct codec_hevc *hevc,
++ struct hevc_frame *frame,
++ struct hevc_frame *col_frame)
++{
++ union rpm_param *param = &hevc->rpm_param;
++ u32 lcu_size_log2 = ilog2(hevc->lcu_size);
++ u32 mv_mem_unit = lcu_size_log2 == 6 ? 0x200 :
++ lcu_size_log2 == 5 ? 0x80 : 0x20;
++ dma_addr_t col_mv_rd_start_addr, col_mv_rd_ptr, col_mv_rd_end_addr;
++ dma_addr_t mpred_mv_wr_ptr;
++ u32 val;
++
++ val = amvdec_read_dos(core, HEVC_MPRED_CURR_LCU);
++
++ col_mv_rd_start_addr = codec_hevc_get_frame_mv_paddr(hevc, col_frame);
++ mpred_mv_wr_ptr = codec_hevc_get_frame_mv_paddr(hevc, frame) +
++ (hevc->slice_addr * mv_mem_unit);
++ col_mv_rd_ptr = col_mv_rd_start_addr +
++ (hevc->slice_addr * mv_mem_unit);
++ col_mv_rd_end_addr = col_mv_rd_start_addr +
++ (hevc->lcu_total * mv_mem_unit);
++
++ amvdec_write_dos(core, HEVC_MPRED_MV_WR_START_ADDR,
++ codec_hevc_get_frame_mv_paddr(hevc, frame));
++ amvdec_write_dos(core, HEVC_MPRED_MV_RD_START_ADDR,
++ col_mv_rd_start_addr);
++
++ if (param->p.slice_segment_address == 0) {
++ amvdec_write_dos(core, HEVC_MPRED_ABV_START_ADDR,
++ hevc->workspace_paddr + MPRED_ABV_OFFSET);
++ amvdec_write_dos(core, HEVC_MPRED_MV_WPTR, mpred_mv_wr_ptr);
++ amvdec_write_dos(core, HEVC_MPRED_MV_RPTR,
++ col_mv_rd_start_addr);
++ } else {
++ amvdec_write_dos(core, HEVC_MPRED_MV_RPTR, col_mv_rd_ptr);
++ }
++
++ amvdec_write_dos(core, HEVC_MPRED_MV_RD_END_ADDR, col_mv_rd_end_addr);
++}
++
++/* Update motion prediction with the current slice */
++static void codec_hevc_set_mpred(struct amvdec_session *sess,
++ struct hevc_frame *frame,
++ struct hevc_frame *col_frame)
++{
++ struct amvdec_core *core = sess->core;
++ struct codec_hevc *hevc = sess->priv;
++ u32 *ref_num = frame->ref_num;
++ u32 *ref_poc_l0 = frame->ref_poc_list[0][frame->cur_slice_idx];
++ u32 *ref_poc_l1 = frame->ref_poc_list[1][frame->cur_slice_idx];
++ u32 val;
++ int i;
++
++ codec_hevc_set_mpred_ctrl(core, hevc);
++ codec_hevc_set_mpred_mv(core, hevc, frame, col_frame);
++
++ amvdec_write_dos(core, HEVC_MPRED_PIC_SIZE,
++ hevc->width | (hevc->height << 16));
++
++ val = ((hevc->lcu_x_num - 1) | (hevc->lcu_y_num - 1) << 16);
++ amvdec_write_dos(core, HEVC_MPRED_PIC_SIZE_LCU, val);
++
++ amvdec_write_dos(core, HEVC_MPRED_REF_NUM,
++ (ref_num[1] << 8) | ref_num[0]);
++ amvdec_write_dos(core, HEVC_MPRED_REF_EN_L0, (1 << ref_num[0]) - 1);
++ amvdec_write_dos(core, HEVC_MPRED_REF_EN_L1, (1 << ref_num[1]) - 1);
++
++ amvdec_write_dos(core, HEVC_MPRED_CUR_POC, hevc->curr_poc);
++ amvdec_write_dos(core, HEVC_MPRED_COL_POC, hevc->col_poc);
++
++ for (i = 0; i < MAX_REF_ACTIVE; ++i) {
++ amvdec_write_dos(core, HEVC_MPRED_L0_REF00_POC + i * 4,
++ ref_poc_l0[i]);
++ amvdec_write_dos(core, HEVC_MPRED_L1_REF00_POC + i * 4,
++ ref_poc_l1[i]);
++ }
++}
++
++/* motion compensation reference cache controller */
++static void codec_hevc_set_mcrcc(struct amvdec_session *sess)
++{
++ struct amvdec_core *core = sess->core;
++ struct codec_hevc *hevc = sess->priv;
++ u32 val, val_2;
++ int l0_cnt = 0;
++ int l1_cnt = 0x7fff;
++
++ if (!codec_hevc_use_fbc(sess->pixfmt_cap, hevc->is_10bit)) {
++ l0_cnt = hevc->cur_frame->ref_num[0];
++ l1_cnt = hevc->cur_frame->ref_num[1];
++ }
++
++ if (hevc->cur_frame->cur_slice_type == I_SLICE) {
++ amvdec_write_dos(core, HEVCD_MCRCC_CTL1, 0);
++ return;
++ }
++
++ if (hevc->cur_frame->cur_slice_type == P_SLICE) {
++ amvdec_write_dos(core, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
++ BIT(1));
++ val = amvdec_read_dos(core, HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
++ val &= 0xffff;
++ val |= (val << 16);
++ amvdec_write_dos(core, HEVCD_MCRCC_CTL2, val);
++
++ if (l0_cnt == 1) {
++ amvdec_write_dos(core, HEVCD_MCRCC_CTL3, val);
++ } else {
++ val = amvdec_read_dos(core,
++ HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
++ val &= 0xffff;
++ val |= (val << 16);
++ amvdec_write_dos(core, HEVCD_MCRCC_CTL3, val);
++ }
++ } else { /* B_SLICE */
++ amvdec_write_dos(core, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, 0);
++ val = amvdec_read_dos(core, HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
++ val &= 0xffff;
++ val |= (val << 16);
++ amvdec_write_dos(core, HEVCD_MCRCC_CTL2, val);
++
++ amvdec_write_dos(core, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
++ BIT(12) | BIT(1));
++ val_2 = amvdec_read_dos(core, HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
++ val_2 &= 0xffff;
++ val_2 |= (val_2 << 16);
++ if (val == val_2 && l1_cnt > 1) {
++ val_2 = amvdec_read_dos(core,
++ HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
++ val_2 &= 0xffff;
++ val_2 |= (val_2 << 16);
++ }
++ amvdec_write_dos(core, HEVCD_MCRCC_CTL3, val);
++ }
++
++ /* enable mcrcc progressive-mode */
++ amvdec_write_dos(core, HEVCD_MCRCC_CTL1, 0xff0);
++}
++
++static void codec_hevc_set_ref_list(struct amvdec_session *sess,
++ u32 ref_num, u32 *ref_poc_list)
++{
++ struct codec_hevc *hevc = sess->priv;
++ struct hevc_frame *ref_frame;
++ struct amvdec_core *core = sess->core;
++ int i;
++ u32 buf_id_y;
++ u32 buf_id_uv;
++
++ for (i = 0; i < ref_num; i++) {
++ ref_frame = codec_hevc_get_frame_by_poc(hevc, ref_poc_list[i]);
++
++ if (!ref_frame) {
++ dev_warn(core->dev, "Couldn't find ref. frame %u\n",
++ ref_poc_list[i]);
++ continue;
++ }
++
++ if (codec_hevc_use_fbc(sess->pixfmt_cap, hevc->is_10bit)) {
++ buf_id_y = buf_id_uv = ref_frame->vbuf->vb2_buf.index;
++ } else {
++ buf_id_y = ref_frame->vbuf->vb2_buf.index * 2;
++ buf_id_uv = buf_id_y + 1;
++ }
++
++ amvdec_write_dos(core, HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
++ (buf_id_uv << 16) |
++ (buf_id_uv << 8) |
++ buf_id_y);
++ }
++}
++
++static void codec_hevc_set_mc(struct amvdec_session *sess,
++ struct hevc_frame *frame)
++{
++ struct amvdec_core *core = sess->core;
++
++ if (frame->cur_slice_type == I_SLICE)
++ return;
++
++ amvdec_write_dos(core, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, 1);
++ codec_hevc_set_ref_list(sess, frame->ref_num[0],
++ frame->ref_poc_list[0][frame->cur_slice_idx]);
++
++ if (frame->cur_slice_type == P_SLICE)
++ return;
++
++ amvdec_write_dos(core, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
++ BIT(12) | BIT(0));
++ codec_hevc_set_ref_list(sess, frame->ref_num[1],
++ frame->ref_poc_list[1][frame->cur_slice_idx]);
++}
++
++static void codec_hevc_update_col_frame(struct codec_hevc *hevc)
++{
++ struct hevc_frame *cur_frame = hevc->cur_frame;
++ union rpm_param *param = &hevc->rpm_param;
++ u32 list_no = 0;
++ u32 col_ref = param->p.collocated_ref_idx;
++ u32 col_from_l0 = param->p.collocated_from_l0_flag;
++ u32 cur_slice_idx = cur_frame->cur_slice_idx;
++
++ if (cur_frame->cur_slice_type == B_SLICE)
++ list_no = 1 - col_from_l0;
++
++ if (col_ref >= cur_frame->ref_num[list_no])
++ hevc->col_poc = INVALID_POC;
++ else
++ hevc->col_poc = cur_frame->ref_poc_list[list_no]
++ [cur_slice_idx]
++ [col_ref];
++
++ if (cur_frame->cur_slice_type == I_SLICE)
++ goto end;
++
++ if (hevc->col_poc != INVALID_POC)
++ hevc->col_frame = codec_hevc_get_frame_by_poc(hevc,
++ hevc->col_poc);
++ else
++ hevc->col_frame = hevc->cur_frame;
++
++end:
++ if (!hevc->col_frame)
++ hevc->col_frame = hevc->cur_frame;
++}
++
++static void codec_hevc_update_pocs(struct amvdec_session *sess)
++{
++ struct codec_hevc *hevc = sess->priv;
++ union rpm_param *param = &hevc->rpm_param;
++ u32 nal_unit_type = param->p.m_nalUnitType;
++ u32 temporal_id = param->p.m_temporalId & 0x7;
++ int max_poc_lsb =
++ 1 << (param->p.log2_max_pic_order_cnt_lsb_minus4 + 4);
++ int prev_poc_lsb;
++ int prev_poc_msb;
++ int poc_msb;
++ int poc_lsb = param->p.POClsb;
++
++ if (nal_unit_type == NAL_UNIT_CODED_SLICE_IDR ||
++ nal_unit_type == NAL_UNIT_CODED_SLICE_IDR_N_LP) {
++ hevc->curr_poc = 0;
++ if ((temporal_id - 1) == 0)
++ hevc->prev_tid0_poc = hevc->curr_poc;
++
++ return;
++ }
++
++ prev_poc_lsb = hevc->prev_tid0_poc % max_poc_lsb;
++ prev_poc_msb = hevc->prev_tid0_poc - prev_poc_lsb;
++
++ if ((poc_lsb < prev_poc_lsb) &&
++ ((prev_poc_lsb - poc_lsb) >= (max_poc_lsb / 2)))
++ poc_msb = prev_poc_msb + max_poc_lsb;
++ else if ((poc_lsb > prev_poc_lsb) &&
++ ((poc_lsb - prev_poc_lsb) > (max_poc_lsb / 2)))
++ poc_msb = prev_poc_msb - max_poc_lsb;
++ else
++ poc_msb = prev_poc_msb;
++
++ if (nal_unit_type == NAL_UNIT_CODED_SLICE_BLA ||
++ nal_unit_type == NAL_UNIT_CODED_SLICE_BLANT ||
++ nal_unit_type == NAL_UNIT_CODED_SLICE_BLA_N_LP)
++ poc_msb = 0;
++
++ hevc->curr_poc = (poc_msb + poc_lsb);
++ if ((temporal_id - 1) == 0)
++ hevc->prev_tid0_poc = hevc->curr_poc;
++}
++
++static void codec_hevc_process_segment_header(struct amvdec_session *sess)
++{
++ struct codec_hevc *hevc = sess->priv;
++ union rpm_param *param = &hevc->rpm_param;
++
++ if (param->p.first_slice_segment_in_pic_flag == 0) {
++ hevc->slice_segment_addr = param->p.slice_segment_address;
++ if (!param->p.dependent_slice_segment_flag)
++ hevc->slice_addr = hevc->slice_segment_addr;
++ } else {
++ hevc->slice_segment_addr = 0;
++ hevc->slice_addr = 0;
++ }
++
++ codec_hevc_update_pocs(sess);
++}
++
++static int codec_hevc_process_segment(struct amvdec_session *sess)
++{
++ struct codec_hevc *hevc = sess->priv;
++ struct amvdec_core *core = sess->core;
++ union rpm_param *param = &hevc->rpm_param;
++ u32 slice_segment_address = param->p.slice_segment_address;
++
++ /* First slice: new frame */
++ if (slice_segment_address == 0) {
++ codec_hevc_update_referenced(hevc);
++ codec_hevc_output_frames(sess);
++
++ hevc->cur_frame = codec_hevc_prepare_new_frame(sess);
++ if (!hevc->cur_frame)
++ return -1;
++ } else {
++ hevc->cur_frame->cur_slice_idx++;
++ }
++
++ codec_hevc_update_frame_refs(sess, hevc->cur_frame);
++ codec_hevc_update_col_frame(hevc);
++ codec_hevc_update_ldc_flag(hevc);
++ if (codec_hevc_use_mmu(core->platform->revision, sess->pixfmt_cap,
++ hevc->is_10bit))
++ codec_hevc_fill_mmu_map(sess, &hevc->common,
++ &hevc->cur_frame->vbuf->vb2_buf,
++ hevc->is_10bit);
++ codec_hevc_set_mc(sess, hevc->cur_frame);
++ codec_hevc_set_mcrcc(sess);
++ codec_hevc_set_mpred(sess, hevc->cur_frame, hevc->col_frame);
++ codec_hevc_set_sao(sess, hevc->cur_frame);
++
++ amvdec_write_dos_bits(core, HEVC_WAIT_FLAG, BIT(1));
++ amvdec_write_dos(core, HEVC_DEC_STATUS_REG,
++ HEVC_CODED_SLICE_SEGMENT_DAT);
++
++ /* Interrupt the firmware's processor */
++ amvdec_write_dos(core, HEVC_MCPU_INTR_REQ, AMRISC_MAIN_REQ);
++
++ return 0;
++}
++
++static int codec_hevc_process_rpm(struct codec_hevc *hevc)
++{
++ union rpm_param *param = &hevc->rpm_param;
++ int src_changed = 0;
++ u32 dst_width, dst_height;
++ u32 lcu_size;
++ u32 is_10bit = 0;
++
++ if (param->p.slice_segment_address ||
++ !param->p.pic_width_in_luma_samples ||
++ !param->p.pic_height_in_luma_samples)
++ return 0;
++
++ if (param->p.bit_depth)
++ is_10bit = 1;
++
++ hevc->width = param->p.pic_width_in_luma_samples;
++ hevc->height = param->p.pic_height_in_luma_samples;
++ dst_width = hevc->width;
++ dst_height = hevc->height;
++
++ lcu_size = 1 << (param->p.log2_min_coding_block_size_minus3 +
++ 3 + param->p.log2_diff_max_min_coding_block_size);
++
++ hevc->lcu_x_num = (hevc->width + lcu_size - 1) / lcu_size;
++ hevc->lcu_y_num = (hevc->height + lcu_size - 1) / lcu_size;
++ hevc->lcu_total = hevc->lcu_x_num * hevc->lcu_y_num;
++
++ if (param->p.conformance_window_flag) {
++ u32 sub_width = 1, sub_height = 1;
++
++ switch (param->p.chroma_format_idc) {
++ case 1:
++ sub_height = 2; /* fallthrough */
++ case 2:
++ sub_width = 2;
++ break;
++ }
++
++ dst_width -= sub_width *
++ (param->p.conf_win_left_offset +
++ param->p.conf_win_right_offset);
++ dst_height -= sub_height *
++ (param->p.conf_win_top_offset +
++ param->p.conf_win_bottom_offset);
++ }
++
++ if (dst_width != hevc->dst_width ||
++ dst_height != hevc->dst_height ||
++ lcu_size != hevc->lcu_size ||
++ is_10bit != hevc->is_10bit)
++ src_changed = 1;
++
++ hevc->dst_width = dst_width;
++ hevc->dst_height = dst_height;
++ hevc->lcu_size = lcu_size;
++ hevc->is_10bit = is_10bit;
++
++ return src_changed;
++}
++
++/*
++ * The RPM section within the workspace contains
++ * many information regarding the parsed bitstream
++ */
++static void codec_hevc_fetch_rpm(struct amvdec_session *sess)
++{
++ struct codec_hevc *hevc = sess->priv;
++ u16 *rpm_vaddr = hevc->workspace_vaddr + RPM_OFFSET;
++ int i, j;
++
++ for (i = 0; i < RPM_SIZE; i += 4)
++ for (j = 0; j < 4; j++)
++ hevc->rpm_param.l.data[i + j] = rpm_vaddr[i + 3 - j];
++}
++
++static void codec_hevc_resume(struct amvdec_session *sess)
++{
++ struct codec_hevc *hevc = sess->priv;
++
++ if (codec_hevc_setup_buffers(sess, &hevc->common, hevc->is_10bit)) {
++ amvdec_abort(sess);
++ return;
++ }
++
++ codec_hevc_setup_decode_head(sess, hevc->is_10bit);
++ codec_hevc_process_segment_header(sess);
++ if (codec_hevc_process_segment(sess))
++ amvdec_abort(sess);
++}
++
++static irqreturn_t codec_hevc_threaded_isr(struct amvdec_session *sess)
++{
++ struct amvdec_core *core = sess->core;
++ struct codec_hevc *hevc = sess->priv;
++ u32 dec_status = amvdec_read_dos(core, HEVC_DEC_STATUS_REG);
++
++ if (!hevc)
++ return IRQ_HANDLED;
++
++ mutex_lock(&hevc->lock);
++ if (dec_status != HEVC_SLICE_SEGMENT_DONE) {
++ dev_err(core->dev_dec, "Unrecognized dec_status: %08X\n",
++ dec_status);
++ amvdec_abort(sess);
++ goto unlock;
++ }
++
++ sess->keyframe_found = 1;
++ codec_hevc_fetch_rpm(sess);
++ if (codec_hevc_process_rpm(hevc)) {
++ amvdec_src_change(sess, hevc->dst_width, hevc->dst_height, 16,
++ hevc->is_10bit ? 10 : 8);
++ goto unlock;
++ }
++
++ codec_hevc_process_segment_header(sess);
++ if (codec_hevc_process_segment(sess))
++ amvdec_abort(sess);
++
++unlock:
++ mutex_unlock(&hevc->lock);
++ return IRQ_HANDLED;
++}
++
++static irqreturn_t codec_hevc_isr(struct amvdec_session *sess)
++{
++ return IRQ_WAKE_THREAD;
++}
++
++struct amvdec_codec_ops codec_hevc_ops = {
++ .start = codec_hevc_start,
++ .stop = codec_hevc_stop,
++ .isr = codec_hevc_isr,
++ .threaded_isr = codec_hevc_threaded_isr,
++ .num_pending_bufs = codec_hevc_num_pending_bufs,
++ .drain = codec_hevc_flush_output,
++ .resume = codec_hevc_resume,
++};
+diff --git a/drivers/staging/media/meson/vdec/codec_hevc.h b/drivers/staging/media/meson/vdec/codec_hevc.h
+new file mode 100644
+index 000000000000..f2f9b2464df1
+--- /dev/null
++++ b/drivers/staging/media/meson/vdec/codec_hevc.h
+@@ -0,0 +1,13 @@
++/* SPDX-License-Identifier: GPL-2.0+ */
++/*
++ * Copyright (C) 2018 Maxime Jourdan <maxi.jourdan@wanadoo.fr>
++ */
++
++#ifndef __MESON_VDEC_CODEC_HEVC_H_
++#define __MESON_VDEC_CODEC_HEVC_H_
++
++#include "vdec.h"
++
++extern struct amvdec_codec_ops codec_hevc_ops;
++
++#endif
+diff --git a/drivers/staging/media/meson/vdec/esparser.c b/drivers/staging/media/meson/vdec/esparser.c
+index 5d2273d53d02..df5956c6141d 100644
+--- a/drivers/staging/media/meson/vdec/esparser.c
++++ b/drivers/staging/media/meson/vdec/esparser.c
+@@ -309,7 +309,7 @@ esparser_queue(struct amvdec_session *sess, struct vb2_v4l2_buffer *vbuf)
+ * they could pause when there is no capture buffer available and
+ * resume on this notification.
+ */
+- if (sess->fmt_out->pixfmt == V4L2_PIX_FMT_VP9) {
++ if (sess->fmt_out->pixfmt == V4L2_PIX_FMT_VP9 || sess->fmt_out->pixfmt ==V4L2_PIX_FMT_HEVC) {
+ if (codec_ops->num_pending_bufs)
+ num_dst_bufs = codec_ops->num_pending_bufs(sess);
+
+diff --git a/drivers/staging/media/meson/vdec/hevc_regs.h b/drivers/staging/media/meson/vdec/hevc_regs.h
+index 0392f41a1eed..e7eabdd2b119 100644
+--- a/drivers/staging/media/meson/vdec/hevc_regs.h
++++ b/drivers/staging/media/meson/vdec/hevc_regs.h
+@@ -205,6 +205,7 @@
+ #define HEVC_CM_HEADER_START_ADDR 0xd8a0
+ #define HEVC_CM_HEADER_LENGTH 0xd8a4
+ #define HEVC_CM_HEADER_OFFSET 0xd8ac
++#define HEVC_SAO_CTRL9 0xd8b4
+ #define HEVC_SAO_MMU_VH0_ADDR 0xd8e8
+ #define HEVC_SAO_MMU_VH1_ADDR 0xd8ec
+
+diff --git a/drivers/staging/media/meson/vdec/vdec_platform.c b/drivers/staging/media/meson/vdec/vdec_platform.c
+index 88c9d72e1c83..8592cb3aaea9 100644
+--- a/drivers/staging/media/meson/vdec/vdec_platform.c
++++ b/drivers/staging/media/meson/vdec/vdec_platform.c
+@@ -11,6 +11,7 @@
+ #include "vdec_hevc.h"
+ #include "codec_mpeg12.h"
+ #include "codec_h264.h"
++#include "codec_hevc.h"
+ #include "codec_vp9.h"
+
+ static const struct amvdec_format vdec_formats_gxbb[] = {
+@@ -64,6 +65,18 @@ static const struct amvdec_format vdec_formats_gxl[] = {
+ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, 0 },
+ .flags = V4L2_FMT_FLAG_COMPRESSED |
+ V4L2_FMT_FLAG_DYN_RESOLUTION,
++ }, {
++ .pixfmt = V4L2_PIX_FMT_HEVC,
++ .min_buffers = 4,
++ .max_buffers = 24,
++ .max_width = 3840,
++ .max_height = 2160,
++ .vdec_ops = &vdec_hevc_ops,
++ .codec_ops = &codec_hevc_ops,
++ .firmware_path = "meson/vdec/gxl_hevc.bin",
++ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, 0 },
++ .flags = V4L2_FMT_FLAG_COMPRESSED |
++ V4L2_FMT_FLAG_DYN_RESOLUTION,
+ }, {
+ .pixfmt = V4L2_PIX_FMT_H264,
+ .min_buffers = 2,
+@@ -114,6 +127,18 @@ static const struct amvdec_format vdec_formats_gxm[] = {
+ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, 0 },
+ .flags = V4L2_FMT_FLAG_COMPRESSED |
+ V4L2_FMT_FLAG_DYN_RESOLUTION,
++ }, {
++ .pixfmt = V4L2_PIX_FMT_HEVC,
++ .min_buffers = 4,
++ .max_buffers = 24,
++ .max_width = 3840,
++ .max_height = 2160,
++ .vdec_ops = &vdec_hevc_ops,
++ .codec_ops = &codec_hevc_ops,
++ .firmware_path = "meson/vdec/gxl_hevc.bin",
++ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, 0 },
++ .flags = V4L2_FMT_FLAG_COMPRESSED |
++ V4L2_FMT_FLAG_DYN_RESOLUTION,
+ }, {
+ .pixfmt = V4L2_PIX_FMT_H264,
+ .min_buffers = 2,
+@@ -165,6 +190,18 @@ static const struct amvdec_format vdec_formats_g12a[] = {
+ .flags = V4L2_FMT_FLAG_COMPRESSED |
+ V4L2_FMT_FLAG_DYN_RESOLUTION,
+ }, {
++ .pixfmt = V4L2_PIX_FMT_HEVC,
++ .min_buffers = 4,
++ .max_buffers = 24,
++ .max_width = 3840,
++ .max_height = 2160,
++ .vdec_ops = &vdec_hevc_ops,
++ .codec_ops = &codec_hevc_ops,
++ .firmware_path = "meson/vdec/g12a_hevc_mmu.bin",
++ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, 0 },
++ .flags = V4L2_FMT_FLAG_COMPRESSED |
++ V4L2_FMT_FLAG_DYN_RESOLUTION,
++ },{
+ .pixfmt = V4L2_PIX_FMT_H264,
+ .min_buffers = 2,
+ .max_buffers = 24,
+@@ -214,6 +251,18 @@ static const struct amvdec_format vdec_formats_sm1[] = {
+ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, 0 },
+ .flags = V4L2_FMT_FLAG_COMPRESSED |
+ V4L2_FMT_FLAG_DYN_RESOLUTION,
++ }, {
++ .pixfmt = V4L2_PIX_FMT_HEVC,
++ .min_buffers = 4,
++ .max_buffers = 24,
++ .max_width = 3840,
++ .max_height = 2160,
++ .vdec_ops = &vdec_hevc_ops,
++ .codec_ops = &codec_hevc_ops,
++ .firmware_path = "meson/vdec/sm1_hevc_mmu.bin",
++ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, 0 },
++ .flags = V4L2_FMT_FLAG_COMPRESSED |
++ V4L2_FMT_FLAG_DYN_RESOLUTION,
+ }, {
+ .pixfmt = V4L2_PIX_FMT_H264,
+ .min_buffers = 2,
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,157 @@
+From 01c7b71f758342efe824f09988a122f1060e3834 Mon Sep 17 00:00:00 2001
+From: benjamin545 <benjamin545@gmail.com>
+Date: Mon, 2 Aug 2021 15:18:40 -0400
+Subject: [PATCH 36/73] WIP: drivers: meson: vdec: add handling to HEVC decoder
+ to show frames when ready
+
+..rather than when no longer referenced
+
+the HEVC decode driver would not show the next frame until it was no longer referenced,
+this would cause a backup of frames that were ready to render but held up by one or more
+frames that were still referenced. The decoded picture buffer would fill up and stall
+playback as no new frames could be placed in the decoded picture buffer.
+---
+ drivers/staging/media/meson/vdec/codec_hevc.c | 52 ++++++++++++-------
+ 1 file changed, 34 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/staging/media/meson/vdec/codec_hevc.c b/drivers/staging/media/meson/vdec/codec_hevc.c
+index 3a6fd04a2d33..01218efde99b 100644
+--- a/drivers/staging/media/meson/vdec/codec_hevc.c
++++ b/drivers/staging/media/meson/vdec/codec_hevc.c
+@@ -223,6 +223,7 @@ struct hevc_frame {
+ u32 poc;
+
+ int referenced;
++ int show;
+ u32 num_reorder_pic;
+
+ u32 cur_slice_idx;
+@@ -448,9 +449,11 @@ static void codec_hevc_update_referenced(struct codec_hevc *hevc)
+ ((1 << (RPS_USED_BIT - 1)) - 1);
+ if (param->p.CUR_RPS[i] & (1 << (RPS_USED_BIT - 1))) {
+ poc_tmp = curr_poc -
+- ((1 << (RPS_USED_BIT - 1)) - delt);
+- } else
++ ((1 << (RPS_USED_BIT - 1)) - delt);
++ } else {
+ poc_tmp = curr_poc + delt;
++ }
++
+ if (poc_tmp == frame->poc) {
+ is_referenced = 1;
+ break;
+@@ -462,13 +465,13 @@ static void codec_hevc_update_referenced(struct codec_hevc *hevc)
+ }
+
+ static struct hevc_frame *
+-codec_hevc_get_lowest_poc_frame(struct codec_hevc *hevc)
++codec_hevc_get_next_ready_frame(struct codec_hevc *hevc)
+ {
+ struct hevc_frame *tmp, *ret = NULL;
+ u32 poc = INT_MAX;
+
+ list_for_each_entry(tmp, &hevc->ref_frames_list, list) {
+- if (tmp->poc < poc) {
++ if ((tmp->poc < poc) && tmp->show) {
+ ret = tmp;
+ poc = tmp->poc;
+ }
+@@ -478,28 +481,35 @@ codec_hevc_get_lowest_poc_frame(struct codec_hevc *hevc)
+ }
+
+ /* Try to output as many frames as possible */
+-static void codec_hevc_output_frames(struct amvdec_session *sess)
++static void codec_hevc_show_frames(struct amvdec_session *sess)
+ {
+- struct hevc_frame *tmp;
++ struct hevc_frame *tmp, *n;
+ struct codec_hevc *hevc = sess->priv;
+
+- while ((tmp = codec_hevc_get_lowest_poc_frame(hevc))) {
++ while ((tmp = codec_hevc_get_next_ready_frame(hevc))) {
+ if (hevc->curr_poc &&
+- (tmp->referenced ||
+- tmp->num_reorder_pic >= hevc->frames_num))
++ (hevc->frames_num <= tmp->num_reorder_pic))
+ break;
+
+ dev_dbg(sess->core->dev, "DONE frame poc %u; vbuf %u\n",
+ tmp->poc, tmp->vbuf->vb2_buf.index);
+ amvdec_dst_buf_done_offset(sess, tmp->vbuf, tmp->offset,
+ V4L2_FIELD_NONE, false);
++
++ tmp->show = 0;
++ hevc->frames_num--;
++ }
++
++ /* clean output frame buffer */
++ list_for_each_entry_safe(tmp, n, &hevc->ref_frames_list, list) {
++ if (tmp->referenced || tmp->show)
++ continue;
++
+ list_del(&tmp->list);
+ kfree(tmp);
+- hevc->frames_num--;
+ }
+ }
+
+-
+ static int
+ codec_hevc_setup_workspace(struct amvdec_session *sess,
+ struct codec_hevc *hevc)
+@@ -650,14 +660,17 @@ static int codec_hevc_start(struct amvdec_session *sess)
+ static void codec_hevc_flush_output(struct amvdec_session *sess)
+ {
+ struct codec_hevc *hevc = sess->priv;
+- struct hevc_frame *tmp;
++ struct hevc_frame *tmp, *n;
+
+- while (!list_empty(&hevc->ref_frames_list)) {
+- tmp = codec_hevc_get_lowest_poc_frame(hevc);
++ while ((tmp = codec_hevc_get_next_ready_frame(hevc))) {
+ amvdec_dst_buf_done(sess, tmp->vbuf, V4L2_FIELD_NONE);
++ tmp->show = 0;
++ hevc->frames_num--;
++ }
++
++ list_for_each_entry_safe(tmp, n, &hevc->ref_frames_list, list) {
+ list_del(&tmp->list);
+ kfree(tmp);
+- hevc->frames_num--;
+ }
+ }
+
+@@ -719,6 +732,7 @@ codec_hevc_prepare_new_frame(struct amvdec_session *sess)
+
+ new_frame->vbuf = vbuf;
+ new_frame->referenced = 1;
++ new_frame->show = 1;
+ new_frame->poc = hevc->curr_poc;
+ new_frame->cur_slice_type = params->p.slice_type;
+ new_frame->num_reorder_pic = params->p.sps_num_reorder_pics_0;
+@@ -1267,7 +1281,7 @@ static int codec_hevc_process_segment(struct amvdec_session *sess)
+ /* First slice: new frame */
+ if (slice_segment_address == 0) {
+ codec_hevc_update_referenced(hevc);
+- codec_hevc_output_frames(sess);
++ codec_hevc_show_frames(sess);
+
+ hevc->cur_frame = codec_hevc_prepare_new_frame(sess);
+ if (!hevc->cur_frame)
+@@ -1370,9 +1384,11 @@ static void codec_hevc_fetch_rpm(struct amvdec_session *sess)
+ u16 *rpm_vaddr = hevc->workspace_vaddr + RPM_OFFSET;
+ int i, j;
+
+- for (i = 0; i < RPM_SIZE; i += 4)
++ for (i = 0; i < RPM_SIZE; i += 4) {
+ for (j = 0; j < 4; j++)
+- hevc->rpm_param.l.data[i + j] = rpm_vaddr[i + 3 - j];
++ hevc->rpm_param.l.data[i + j] =
++ rpm_vaddr[i + 3 - j];
++ }
+ }
+
+ static void codec_hevc_resume(struct amvdec_session *sess)
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,39 @@
+From 514962e3e5743b5d0e1b9add082b27f1a17d535d Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Sun, 21 Nov 2021 19:12:07 +0000
+Subject: [PATCH 37/73] WIP: drivers: meson: vdec: add HEVC support to GXBB
+
+It's not clear whether the GXL firmware is the same one used with GXBB
+but let's try it and see!
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ drivers/staging/media/meson/vdec/vdec_platform.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/drivers/staging/media/meson/vdec/vdec_platform.c b/drivers/staging/media/meson/vdec/vdec_platform.c
+index 8592cb3aaea9..810039a02b44 100644
+--- a/drivers/staging/media/meson/vdec/vdec_platform.c
++++ b/drivers/staging/media/meson/vdec/vdec_platform.c
+@@ -16,6 +16,18 @@
+
+ static const struct amvdec_format vdec_formats_gxbb[] = {
+ {
++ .pixfmt = V4L2_PIX_FMT_HEVC,
++ .min_buffers = 4,
++ .max_buffers = 24,
++ .max_width = 3840,
++ .max_height = 2160,
++ .vdec_ops = &vdec_hevc_ops,
++ .codec_ops = &codec_hevc_ops,
++ .firmware_path = "meson/vdec/gxl_hevc.bin",
++ .pixfmts_cap = { V4L2_PIX_FMT_NV12M, 0 },
++ .flags = V4L2_FMT_FLAG_COMPRESSED |
++ V4L2_FMT_FLAG_DYN_RESOLUTION,
++ }, {
+ .pixfmt = V4L2_PIX_FMT_H264,
+ .min_buffers = 2,
+ .max_buffers = 24,
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,51 @@
+From 8d43f5852bdc1a6925e45c57de499ad61547cde1 Mon Sep 17 00:00:00 2001
+From: Neil Armstrong <narmstrong@baylibre.com>
+Date: Mon, 22 Nov 2021 09:15:21 +0000
+Subject: [PATCH 38/73] WIP: drivers: meson: vdec: check if parser has really
+ parser before marking input buffer as error
+
+Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
+---
+ drivers/staging/media/meson/vdec/esparser.c | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/staging/media/meson/vdec/esparser.c b/drivers/staging/media/meson/vdec/esparser.c
+index df5956c6141d..06f627b141fb 100644
+--- a/drivers/staging/media/meson/vdec/esparser.c
++++ b/drivers/staging/media/meson/vdec/esparser.c
+@@ -300,6 +300,7 @@ esparser_queue(struct amvdec_session *sess, struct vb2_v4l2_buffer *vbuf)
+ u32 num_dst_bufs = 0;
+ u32 offset;
+ u32 pad_size;
++ u32 wp, wp2;
+
+ /*
+ * When max ref frame is held by VP9, this should be -= 3 to prevent a
+@@ -354,15 +355,20 @@ esparser_queue(struct amvdec_session *sess, struct vb2_v4l2_buffer *vbuf)
+ }
+
+ pad_size = esparser_pad_start_code(core, vb, payload_size);
++ wp = amvdec_read_parser(core, PARSER_VIDEO_WP);
+ ret = esparser_write_data(core, phy, payload_size + pad_size);
++ wp2 = amvdec_read_parser(core, PARSER_VIDEO_WP);
+
+ if (ret <= 0) {
+- dev_warn(core->dev, "esparser: input parsing error\n");
+- amvdec_remove_ts(sess, vb->timestamp);
+- v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
+ amvdec_write_parser(core, PARSER_FETCH_CMD, 0);
+
+- return 0;
++ if (ret < 0 || wp2 == wp) {
++ dev_err(core->dev, "esparser: input parsing error ret %d (%x <=> %x)\n", ret, wp, wp2);
++ amvdec_remove_ts(sess, vb->timestamp);
++ v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
++
++ return 0;
++ }
+ }
+
+ atomic_inc(&sess->esparser_queued_bufs);
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,94 @@
+From 2e5d82b4f096bb5abe901f491e1612a23b332c5d Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Tue, 17 Aug 2021 16:16:43 +0000
+Subject: [PATCH 39/73] WIP: arm64: dts: meson: radxa-zero: add support for the
+ usb type-c controller
+
+Radxa Zero uses an FUSB302 type-c controller, so lets enable it.
+
+NB: Polarity swapping via GPIO is not implemented in the current driver
+(see drivers/usb/typec/tcpm/fusb302.c) so it is not possible to handle
+GPIOAO_6 for USB3 polarity control.
+
+Suggested-by: Neil Armstrong <narmstrong@baylibre.com>
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ .../dts/amlogic/meson-g12a-radxa-zero.dts | 44 +++++++++++++++++++
+ 1 file changed, 44 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-radxa-zero.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-radxa-zero.dts
+index e3bb6df42ff3..5e3dc013409f 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-g12a-radxa-zero.dts
++++ b/arch/arm64/boot/dts/amlogic/meson-g12a-radxa-zero.dts
+@@ -60,6 +60,14 @@
+ clock-names = "ext_clock";
+ };
+
++ typec2_vbus: regulator-typec2_vbus {
++ compatible = "regulator-fixed";
++ regulator-name = "TYPEC2_VBUS";
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ vin-supply = <&ao_5v>;
++ };
++
+ ao_5v: regulator-ao_5v {
+ compatible = "regulator-fixed";
+ regulator-name = "AO_5V";
+@@ -191,6 +199,18 @@
+ };
+ };
+
++&ao_pinctrl {
++ /* Ensure the TYPE C controller irq pin is not driven by the SoC */
++ fusb302_irq_pins: fusb302_irq {
++ mux {
++ groups = "GPIOAO_5";
++ function = "gpio_aobus";
++ bias-pull-up;
++ output-disable;
++ };
++ };
++};
++
+ &arb {
+ status = "okay";
+ };
+@@ -278,6 +298,22 @@
+ pinctrl-names = "default";
+ };
+
++&i2c_AO {
++ fusb302@22 {
++ compatible = "fcs,fusb302";
++ reg = <0x22>;
++
++ pinctrl-0 = <&fusb302_irq_pins>;
++ pinctrl-names = "default";
++ interrupt-parent = <&gpio_intc>;
++ interrupts = <59 IRQ_TYPE_LEVEL_LOW>;
++
++ vbus-supply = <&typec2_vbus>;
++
++ status = "okay";
++ };
++};
++
+ &pwm_AO_cd {
+ pinctrl-0 = <&pwm_ao_d_e_pins>;
+ pinctrl-names = "default";
+@@ -403,3 +439,11 @@
+ status = "okay";
+ dr_mode = "host";
+ };
++
++&usb2_phy0 {
++ phy-supply = <&typec2_vbus>;
++};
++
++&usb3_pcie_phy {
++ phy-supply = <&typec2_vbus>;
++};
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,29 @@
+From 0fb9861b7c3cc0a598ef0ad6544c3ef3ebc1e3cc Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Wed, 16 Feb 2022 07:27:07 +0000
+Subject: [PATCH 40/73] WIP: dt-bindings: arm: amlogic: add support for Radxa
+ Zero2
+
+The Radxa Zero2 is a small form-factor SBC using the Amlogic
+A311D chip.
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ Documentation/devicetree/bindings/arm/amlogic.yaml | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
+index 3217c069673e..ea4f016082c4 100644
+--- a/Documentation/devicetree/bindings/arm/amlogic.yaml
++++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
+@@ -153,6 +153,7 @@ properties:
+ items:
+ - enum:
+ - khadas,vim3
++ - radxa,zero2
+ - const: amlogic,a311d
+ - const: amlogic,g12b
+
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,547 @@
+From 92ce99d7dc9d6aca6bcebbdb99b032b32ec39f81 Mon Sep 17 00:00:00 2001
+From: Yuntian Zhang <yt@radxa.com>
+Date: Fri, 14 Jan 2022 15:50:02 +0000
+Subject: [PATCH 41/73] WIP: arm64: dts: meson: add support for Radxa Zero2
+
+Radxa Zero2 is a small form factor SBC based on the Amlogic A311D
+chipset that ships in a number of eMMC configurations:
+
+- Amlogic A311D (Quad A73 + Dual A53) CPU
+- 4GB LPDDR4 RAM
+- 32/64/128GB eMMC
+- Mali G52-MP4 GPU
+- HDMI 2.1 output (micro)
+- BCM4345 WiFi (2.4/5GHz a/b/g/n/ac) and BT 5.0
+- 1x USB 2.0 port - Type C (OTG)
+- 1x USB 3.0 port - Type C (Host)
+- 1x micro SD Card slot
+- 40 Pin GPIO header
+
+Signed-off-by: Yuntian Zhang <yt@radxa.com>
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ arch/arm64/boot/dts/amlogic/Makefile | 1 +
+ .../dts/amlogic/meson-g12b-radxa-zero2.dts | 499 ++++++++++++++++++
+ 2 files changed, 500 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/amlogic/meson-g12b-radxa-zero2.dts
+
+diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
+index 641399fcbdd9..5eaaeb620a17 100644
+--- a/arch/arm64/boot/dts/amlogic/Makefile
++++ b/arch/arm64/boot/dts/amlogic/Makefile
+@@ -12,6 +12,7 @@ dtb-$(CONFIG_ARCH_MESON) += meson-g12b-gtking-pro.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-g12b-gtking.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-g12b-odroid-n2-plus.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-g12b-odroid-n2.dtb
++dtb-$(CONFIG_ARCH_MESON) += meson-g12b-radxa-zero2.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-g12b-s922x-khadas-vim3.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-g12b-ugoos-am6.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-kii-pro.dtb
+diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-radxa-zero2.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-radxa-zero2.dts
+new file mode 100644
+index 000000000000..fefa6f2b7abf
+--- /dev/null
++++ b/arch/arm64/boot/dts/amlogic/meson-g12b-radxa-zero2.dts
+@@ -0,0 +1,499 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++/*
++ * Copyright (c) 2019 BayLibre, SAS
++ * Author: Neil Armstrong <narmstrong@baylibre.com>
++ * Copyright (c) 2019 Christian Hewitt <christianshewitt@gmail.com>
++ * Copyright (c) 2022 Radxa Limited
++ * Author: Yuntian Zhang <yt@radxa.com>
++ */
++
++/dts-v1/;
++
++#include "meson-g12b-a311d.dtsi"
++#include <dt-bindings/input/input.h>
++#include <dt-bindings/leds/common.h>
++#include <dt-bindings/gpio/meson-g12a-gpio.h>
++#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
++
++/ {
++ compatible = "radxa,zero2", "amlogic,a311d", "amlogic,g12b";
++ model = "Radxa Zero2";
++
++ aliases {
++ serial0 = &uart_AO;
++ serial2 = &uart_A;
++ };
++
++ chosen {
++ stdout-path = "serial0:115200n8";
++ };
++
++ memory@0 {
++ device_type = "memory";
++ reg = <0x0 0x0 0x0 0x80000000>;
++ };
++
++ gpio-keys-polled {
++ compatible = "gpio-keys-polled";
++ poll-interval = <100>;
++ power-button {
++ label = "power";
++ linux,code = <KEY_POWER>;
++ gpios = <&gpio_ao GPIOAO_3 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
++ };
++ };
++
++ leds {
++ compatible = "gpio-leds";
++
++ led-green {
++ color = <LED_COLOR_ID_GREEN>;
++ function = LED_FUNCTION_STATUS;
++ gpios = <&gpio GPIOA_12 GPIO_ACTIVE_HIGH>;
++ linux,default-trigger = "heartbeat";
++ };
++ };
++
++ cvbs-connector {
++ status = "disabled";
++ compatible = "composite-video-connector";
++
++ port {
++ cvbs_connector_in: endpoint {
++ remote-endpoint = <&cvbs_vdac_out>;
++ };
++ };
++ };
++
++ hdmi-connector {
++ compatible = "hdmi-connector";
++ type = "a";
++
++ port {
++ hdmi_connector_in: endpoint {
++ remote-endpoint = <&hdmi_tx_tmds_out>;
++ };
++ };
++ };
++
++ emmc_pwrseq: emmc-pwrseq {
++ compatible = "mmc-pwrseq-emmc";
++ reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>;
++ };
++
++ sdio_pwrseq: sdio-pwrseq {
++ compatible = "mmc-pwrseq-simple";
++ reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
++ clocks = <&wifi32k>;
++ clock-names = "ext_clock";
++ };
++
++ ao_5v: regulator-ao_5v {
++ compatible = "regulator-fixed";
++ regulator-name = "AO_5V";
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ regulator-always-on;
++ };
++
++ vcc_1v8: regulator-vcc_1v8 {
++ compatible = "regulator-fixed";
++ regulator-name = "VCC_1V8";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ vin-supply = <&vcc_3v3>;
++ regulator-always-on;
++ };
++
++ vcc_3v3: regulator-vcc_3v3 {
++ compatible = "regulator-fixed";
++ regulator-name = "VCC_3V3";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ vin-supply = <&vddao_3v3>;
++ regulator-always-on;
++ /* FIXME: actually controlled by VDDCPU_B_EN */
++ };
++
++ vddao_1v8: regulator-vddao_1v8 {
++ compatible = "regulator-fixed";
++ regulator-name = "VDDIO_AO1V8";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ vin-supply = <&vddao_3v3>;
++ regulator-always-on;
++ };
++
++ vddao_3v3: regulator-vddao_3v3 {
++ compatible = "regulator-fixed";
++ regulator-name = "VDDAO_3V3";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ vin-supply = <&ao_5v>;
++ regulator-always-on;
++ };
++
++ vddcpu_a: regulator-vddcpu-a {
++ /*
++ * MP8756GD Regulator.
++ */
++ compatible = "pwm-regulator";
++
++ regulator-name = "VDDCPU_A";
++ regulator-min-microvolt = <730000>;
++ regulator-max-microvolt = <1022000>;
++
++ pwm-supply = <&ao_5v>;
++
++ pwms = <&pwm_ab 0 1250 0>;
++ pwm-dutycycle-range = <100 0>;
++
++ regulator-boot-on;
++ regulator-always-on;
++ };
++
++ vddcpu_b: regulator-vddcpu-b {
++ /*
++ * Silergy SY8120B1ABC Regulator.
++ */
++ compatible = "pwm-regulator";
++
++ regulator-name = "VDDCPU_B";
++ regulator-min-microvolt = <730000>;
++ regulator-max-microvolt = <1022000>;
++
++ pwm-supply = <&ao_5v>;
++
++ pwms = <&pwm_AO_cd 1 1250 0>;
++ pwm-dutycycle-range = <100 0>;
++
++ regulator-boot-on;
++ regulator-always-on;
++ };
++
++ sound {
++ compatible = "amlogic,axg-sound-card";
++ model = "RADXA-ZERO2";
++ audio-aux-devs = <&tdmout_b>;
++ audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
++ "TDMOUT_B IN 1", "FRDDR_B OUT 1",
++ "TDMOUT_B IN 2", "FRDDR_C OUT 1",
++ "TDM_B Playback", "TDMOUT_B OUT";
++
++ assigned-clocks = <&clkc CLKID_MPLL2>,
++ <&clkc CLKID_MPLL0>,
++ <&clkc CLKID_MPLL1>;
++ assigned-clock-parents = <0>, <0>, <0>;
++ assigned-clock-rates = <294912000>,
++ <270950400>,
++ <393216000>;
++ status = "okay";
++
++ dai-link-0 {
++ sound-dai = <&frddr_a>;
++ };
++
++ dai-link-1 {
++ sound-dai = <&frddr_b>;
++ };
++
++ dai-link-2 {
++ sound-dai = <&frddr_c>;
++ };
++
++ /* 8ch hdmi interface */
++ dai-link-3 {
++ sound-dai = <&tdmif_b>;
++ dai-format = "i2s";
++ dai-tdm-slot-tx-mask-0 = <1 1>;
++ dai-tdm-slot-tx-mask-1 = <1 1>;
++ dai-tdm-slot-tx-mask-2 = <1 1>;
++ dai-tdm-slot-tx-mask-3 = <1 1>;
++ mclk-fs = <256>;
++
++ codec {
++ sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
++ };
++ };
++
++ /* hdmi glue */
++ dai-link-4 {
++ sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
++
++ codec {
++ sound-dai = <&hdmi_tx>;
++ };
++ };
++ };
++
++ wifi32k: wifi32k {
++ compatible = "pwm-clock";
++ #clock-cells = <0>;
++ clock-frequency = <32768>;
++ pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */
++ };
++};
++
++&arb {
++ status = "okay";
++};
++
++&cec_AO {
++ pinctrl-0 = <&cec_ao_a_h_pins>;
++ pinctrl-names = "default";
++ status = "disabled";
++ hdmi-phandle = <&hdmi_tx>;
++};
++
++&cecb_AO {
++ pinctrl-0 = <&cec_ao_b_h_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++ hdmi-phandle = <&hdmi_tx>;
++};
++
++&clkc_audio {
++ status = "okay";
++};
++
++&cpu0 {
++ cpu-supply = <&vddcpu_b>;
++ operating-points-v2 = <&cpu_opp_table_0>;
++ clocks = <&clkc CLKID_CPU_CLK>;
++ clock-latency = <50000>;
++};
++
++&cpu1 {
++ cpu-supply = <&vddcpu_b>;
++ operating-points-v2 = <&cpu_opp_table_0>;
++ clocks = <&clkc CLKID_CPU_CLK>;
++ clock-latency = <50000>;
++};
++
++&cpu100 {
++ cpu-supply = <&vddcpu_a>;
++ operating-points-v2 = <&cpub_opp_table_1>;
++ clocks = <&clkc CLKID_CPUB_CLK>;
++ clock-latency = <50000>;
++};
++
++&cpu101 {
++ cpu-supply = <&vddcpu_a>;
++ operating-points-v2 = <&cpub_opp_table_1>;
++ clocks = <&clkc CLKID_CPUB_CLK>;
++ clock-latency = <50000>;
++};
++
++&cpu102 {
++ cpu-supply = <&vddcpu_a>;
++ operating-points-v2 = <&cpub_opp_table_1>;
++ clocks = <&clkc CLKID_CPUB_CLK>;
++ clock-latency = <50000>;
++};
++
++&cpu103 {
++ cpu-supply = <&vddcpu_a>;
++ operating-points-v2 = <&cpub_opp_table_1>;
++ clocks = <&clkc CLKID_CPUB_CLK>;
++ clock-latency = <50000>;
++};
++
++&cvbs_vdac_port {
++ cvbs_vdac_out: endpoint {
++ remote-endpoint = <&cvbs_connector_in>;
++ };
++};
++
++&frddr_a {
++ status = "okay";
++};
++
++&frddr_b {
++ status = "okay";
++};
++
++&frddr_c {
++ status = "okay";
++};
++
++&gpio {
++ gpio-line-names =
++ /* GPIOZ */
++ "PIN_27", "PIN_28", "PIN_7", "PIN_11", "PIN_13", "PIN_15", "PIN_18", "PIN_40",
++ "", "", "", "", "", "", "", "",
++ /* GPIOH */
++ "", "", "", "", "PIN_19", "PIN_21", "PIN_24", "PIN_23",
++ "",
++ /* BOOT */
++ "", "", "", "", "", "", "", "",
++ "", "", "", "", "EMMC_PWRSEQ", "", "", "",
++ /* GPIOC */
++ "", "", "", "", "", "", "SD_CD", "PIN_36",
++ /* GPIOA */
++ "PIN_32", "PIN_12", "PIN_35", "", "", "PIN_38", "", "",
++ "", "", "", "", "LED_GREEN", "PIN_31", "PIN_3", "PIN_5",
++ /* GPIOX */
++ "", "", "", "", "", "", "SDIO_PWRSEQ", "",
++ "", "", "", "", "", "", "", "",
++ "", "BT_SHUTDOWN", "", "";
++};
++
++&gpio_ao {
++ gpio-line-names =
++ /* GPIOAO */
++ "PIN_8", "PIN_10", "", "BTN_POWER", "", "", "", "PIN_29",
++ "PIN_33", "PIN_37", "FAN", "",
++ /* GPIOE */
++ "", "", "";
++};
++
++&hdmi_tx {
++ status = "okay";
++ pinctrl-0 = <&hdmitx_hpd_pins>, <&hdmitx_ddc_pins>;
++ pinctrl-names = "default";
++ hdmi-supply = <&ao_5v>;
++};
++
++&hdmi_tx_tmds_port {
++ hdmi_tx_tmds_out: endpoint {
++ remote-endpoint = <&hdmi_connector_in>;
++ };
++};
++
++&ir {
++ status = "disabled";
++ pinctrl-0 = <&remote_input_ao_pins>;
++ pinctrl-names = "default";
++};
++
++&pwm_ab {
++ pinctrl-0 = <&pwm_a_e_pins>;
++ pinctrl-names = "default";
++ clocks = <&xtal>;
++ clock-names = "clkin0";
++ status = "okay";
++};
++
++&pwm_ef {
++ pinctrl-0 = <&pwm_e_pins>;
++ pinctrl-names = "default";
++ clocks = <&xtal>;
++ clock-names = "clkin2";
++ status = "okay";
++};
++
++&pwm_AO_cd {
++ pinctrl-0 = <&pwm_ao_d_e_pins>;
++ pinctrl-names = "default";
++ clocks = <&xtal>;
++ clock-names = "clkin4";
++ status = "okay";
++};
++
++&saradc {
++ status = "okay";
++ vref-supply = <&vddao_1v8>;
++};
++
++/* SDIO */
++&sd_emmc_a {
++ status = "okay";
++ pinctrl-0 = <&sdio_pins>;
++ pinctrl-1 = <&sdio_clk_gate_pins>;
++ pinctrl-names = "default", "clk-gate";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ bus-width = <4>;
++ cap-sd-highspeed;
++ max-frequency = <100000000>;
++
++ non-removable;
++ disable-wp;
++
++ /* WiFi firmware requires power to be kept while in suspend */
++ keep-power-in-suspend;
++
++ mmc-pwrseq = <&sdio_pwrseq>;
++
++ vmmc-supply = <&vddao_3v3>;
++ vqmmc-supply = <&vddao_1v8>;
++
++ brcmf: wifi@1 {
++ reg = <1>;
++ compatible = "brcm,bcm4329-fmac";
++ };
++};
++
++/* SD card */
++&sd_emmc_b {
++ status = "okay";
++ pinctrl-0 = <&sdcard_c_pins>;
++ pinctrl-1 = <&sdcard_clk_gate_c_pins>;
++ pinctrl-names = "default", "clk-gate";
++
++ bus-width = <4>;
++ cap-sd-highspeed;
++ max-frequency = <50000000>;
++ disable-wp;
++
++ cd-gpios = <&gpio GPIOC_6 GPIO_ACTIVE_LOW>;
++ vmmc-supply = <&vddao_3v3>;
++ vqmmc-supply = <&vddao_3v3>;
++};
++
++/* eMMC */
++&sd_emmc_c {
++ status = "okay";
++ pinctrl-0 = <&emmc_ctrl_pins>, <&emmc_data_8b_pins>, <&emmc_ds_pins>;
++ pinctrl-1 = <&emmc_clk_gate_pins>;
++ pinctrl-names = "default", "clk-gate";
++
++ bus-width = <8>;
++ cap-mmc-highspeed;
++ mmc-ddr-1_8v;
++ mmc-hs200-1_8v;
++ max-frequency = <200000000>;
++ disable-wp;
++
++ mmc-pwrseq = <&emmc_pwrseq>;
++ vmmc-supply = <&vcc_3v3>;
++ vqmmc-supply = <&vcc_1v8>;
++};
++
++&tdmif_b {
++ status = "okay";
++};
++
++&tdmout_b {
++ status = "okay";
++};
++
++&tohdmitx {
++ status = "okay";
++};
++
++&uart_A {
++ status = "okay";
++ pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>;
++ pinctrl-names = "default";
++ uart-has-rtscts;
++
++ bluetooth {
++ compatible = "brcm,bcm43438-bt";
++ shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
++ max-speed = <2000000>;
++ clocks = <&wifi32k>;
++ clock-names = "lpo";
++ };
++};
++
++&uart_AO {
++ status = "okay";
++ pinctrl-0 = <&uart_ao_a_pins>;
++ pinctrl-names = "default";
++};
++
++&usb {
++ status = "okay";
++};
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,70 @@
+From f0102e5d910b47aa4f46e2757a8e4b9cd820ae7c Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Fri, 15 May 2020 07:52:47 +0000
+Subject: [PATCH 42/73] WIP: arm64: dts: meson: add audio playback to p201
+
+Add initial audio support limited to HDMI i2s.
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ .../boot/dts/amlogic/meson-gxbb-p201.dts | 40 +++++++++++++++++++
+ 1 file changed, 40 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p201.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-p201.dts
+index 150a82f3b2d7..22bd0070146b 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p201.dts
++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p201.dts
+@@ -8,10 +8,50 @@
+ /dts-v1/;
+
+ #include "meson-gxbb-p20x.dtsi"
++#include <dt-bindings/sound/meson-aiu.h>
+
+ / {
+ compatible = "amlogic,p201", "amlogic,meson-gxbb";
+ model = "Amlogic Meson GXBB P201 Development Board";
++
++ sound {
++ compatible = "amlogic,gx-sound-card";
++ model = "P201";
++ assigned-clocks = <&clkc CLKID_MPLL0>,
++ <&clkc CLKID_MPLL1>,
++ <&clkc CLKID_MPLL2>;
++ assigned-clock-parents = <0>, <0>, <0>;
++ assigned-clock-rates = <294912000>,
++ <270950400>,
++ <393216000>;
++ status = "okay";
++
++ dai-link-0 {
++ sound-dai = <&aiu AIU_CPU CPU_I2S_FIFO>;
++ };
++
++ dai-link-1 {
++ sound-dai = <&aiu AIU_CPU CPU_I2S_ENCODER>;
++ dai-format = "i2s";
++ mclk-fs = <256>;
++
++ codec-0 {
++ sound-dai = <&aiu AIU_HDMI CTRL_I2S>;
++ };
++ };
++
++ dai-link-2 {
++ sound-dai = <&aiu AIU_HDMI CTRL_OUT>;
++
++ codec-0 {
++ sound-dai = <&hdmi_tx>;
++ };
++ };
++ };
++};
++
++&aiu {
++ status = "okay";
+ };
+
+ ðmac {
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,99 @@
+From cbba90f273a4af2f08f6286bca65c49b96ff44d4 Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Fri, 15 May 2020 07:56:15 +0000
+Subject: [PATCH 43/73] WIP: arm64: dts: meson: add audio playback to p200
+
+Add initial support limited to HDMI i2s and SPDIF (LPCM).
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ .../boot/dts/amlogic/meson-gxbb-p200.dts | 61 +++++++++++++++++++
+ 1 file changed, 61 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts
+index 3c93d1898b40..27b3ab20f070 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts
++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts
+@@ -9,11 +9,19 @@
+
+ #include "meson-gxbb-p20x.dtsi"
+ #include <dt-bindings/input/input.h>
++#include <dt-bindings/sound/meson-aiu.h>
+
+ / {
+ compatible = "amlogic,p200", "amlogic,meson-gxbb";
+ model = "Amlogic Meson GXBB P200 Development Board";
+
++ spdif_dit: audio-codec-0 {
++ #sound-dai-cells = <0>;
++ compatible = "linux,spdif-dit";
++ status = "okay";
++ sound-name-prefix = "DIT";
++ };
++
+ avdd18_usb_adc: regulator-avdd18_usb_adc {
+ compatible = "regulator-fixed";
+ regulator-name = "AVDD18_USB_ADC";
+@@ -57,6 +65,59 @@
+ press-threshold-microvolt = <0>; /* 0% */
+ };
+ };
++
++ sound {
++ compatible = "amlogic,gx-sound-card";
++ model = "P200";
++ assigned-clocks = <&clkc CLKID_MPLL0>,
++ <&clkc CLKID_MPLL1>,
++ <&clkc CLKID_MPLL2>;
++ assigned-clock-parents = <0>, <0>, <0>;
++ assigned-clock-rates = <294912000>,
++ <270950400>,
++ <393216000>;
++ status = "okay";
++
++ dai-link-0 {
++ sound-dai = <&aiu AIU_CPU CPU_I2S_FIFO>;
++ };
++
++ dai-link-1 {
++ sound-dai = <&aiu AIU_CPU CPU_SPDIF_FIFO>;
++ };
++
++ dai-link-2 {
++ sound-dai = <&aiu AIU_CPU CPU_I2S_ENCODER>;
++ dai-format = "i2s";
++ mclk-fs = <256>;
++
++ codec-0 {
++ sound-dai = <&aiu AIU_HDMI CTRL_I2S>;
++ };
++ };
++
++ dai-link-3 {
++ sound-dai = <&aiu AIU_CPU CPU_SPDIF_ENCODER>;
++
++ codec-0 {
++ sound-dai = <&spdif_dit>;
++ };
++ };
++
++ dai-link-4 {
++ sound-dai = <&aiu AIU_HDMI CTRL_OUT>;
++
++ codec-0 {
++ sound-dai = <&hdmi_tx>;
++ };
++ };
++ };
++};
++
++&aiu {
++ status = "okay";
++ pinctrl-0 = <&spdif_out_y_pins>;
++ pinctrl-names = "default";
+ };
+
+ ðmac {
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,191 @@
+From e708a7770bd3d6f557bf31b7fa921af5e38d68ff Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Sun, 17 May 2020 05:00:55 +0000
+Subject: [PATCH 44/73] WIP: arm64: dts: meson: add audio playback to u200
+
+Add initial support limited to HDMI i2s and SPDIF (LPCM).
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ .../boot/dts/amlogic/meson-g12a-u200.dts | 130 ++++++++++++++++++
+ 1 file changed, 130 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts
+index 4b5d11e56364..61a85c27a463 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts
++++ b/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts
+@@ -8,6 +8,7 @@
+ #include "meson-g12a.dtsi"
+ #include <dt-bindings/gpio/gpio.h>
+ #include <dt-bindings/gpio/meson-g12a-gpio.h>
++#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+ / {
+ compatible = "amlogic,u200", "amlogic,g12a";
+@@ -18,6 +19,13 @@
+ ethernet0 = ðmac;
+ };
+
++ spdif_dit: audio-codec-1 {
++ #sound-dai-cells = <0>;
++ compatible = "linux,spdif-dit";
++ status = "okay";
++ sound-name-prefix = "DIT";
++ };
++
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+@@ -147,6 +155,90 @@
+ regulator-boot-on;
+ regulator-always-on;
+ };
++
++ sound {
++ compatible = "amlogic,axg-sound-card";
++ model = "U200";
++ audio-aux-devs = <&tdmout_b>;
++ audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
++ "TDMOUT_B IN 1", "FRDDR_B OUT 1",
++ "TDMOUT_B IN 2", "FRDDR_C OUT 1",
++ "TDM_B Playback", "TDMOUT_B OUT",
++ "SPDIFOUT IN 0", "FRDDR_A OUT 3",
++ "SPDIFOUT IN 1", "FRDDR_B OUT 3",
++ "SPDIFOUT IN 2", "FRDDR_C OUT 3";
++
++ assigned-clocks = <&clkc CLKID_MPLL2>,
++ <&clkc CLKID_MPLL0>,
++ <&clkc CLKID_MPLL1>;
++ assigned-clock-parents = <0>, <0>, <0>;
++ assigned-clock-rates = <294912000>,
++ <270950400>,
++ <393216000>;
++ status = "okay";
++
++ dai-link-0 {
++ sound-dai = <&frddr_a>;
++ };
++
++ dai-link-1 {
++ sound-dai = <&frddr_b>;
++ };
++
++ dai-link-2 {
++ sound-dai = <&frddr_c>;
++ };
++
++ /* 8ch hdmi interface */
++ dai-link-3 {
++ sound-dai = <&tdmif_b>;
++ dai-format = "i2s";
++ dai-tdm-slot-tx-mask-0 = <1 1>;
++ dai-tdm-slot-tx-mask-1 = <1 1>;
++ dai-tdm-slot-tx-mask-2 = <1 1>;
++ dai-tdm-slot-tx-mask-3 = <1 1>;
++ mclk-fs = <256>;
++
++ codec {
++ sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
++ };
++ };
++
++ /* spdif hdmi or toslink interface */
++ dai-link-4 {
++ sound-dai = <&spdifout>;
++
++ codec-0 {
++ sound-dai = <&spdif_dit>;
++ };
++
++ codec-1 {
++ sound-dai = <&tohdmitx TOHDMITX_SPDIF_IN_A>;
++ };
++ };
++
++ /* spdif hdmi interface */
++ dai-link-5 {
++ sound-dai = <&spdifout_b>;
++
++ codec {
++ sound-dai = <&tohdmitx TOHDMITX_SPDIF_IN_B>;
++ };
++ };
++
++ /* hdmi glue */
++ dai-link-6 {
++ sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
++
++ codec {
++ sound-dai = <&hdmi_tx>;
++ };
++ };
++ };
++};
++
++&arb {
++ status = "okay";
+ };
+
+ &cec_AO {
+@@ -163,6 +255,10 @@
+ hdmi-phandle = <&hdmi_tx>;
+ };
+
++&clkc_audio {
++ status = "okay";
++};
++
+ &cpu0 {
+ cpu-supply = <&vddcpu>;
+ operating-points-v2 = <&cpu_opp_table>;
+@@ -203,6 +299,18 @@
+ phy-mode = "rmii";
+ };
+
++&frddr_a {
++ status = "okay";
++};
++
++&frddr_b {
++ status = "okay";
++};
++
++&frddr_c {
++ status = "okay";
++};
++
+ &hdmi_tx {
+ status = "okay";
+ pinctrl-0 = <&hdmitx_hpd_pins>, <&hdmitx_ddc_pins>;
+@@ -288,6 +396,28 @@
+ vqmmc-supply = <&flash_1v8>;
+ };
+
++&spdifout {
++ pinctrl-0 = <&spdif_out_h_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++};
++
++&spdifout_b {
++ status = "okay";
++};
++
++&tdmif_b {
++ status = "okay";
++};
++
++&tdmout_b {
++ status = "okay";
++};
++
++&tohdmitx {
++ status = "okay";
++};
++
+ &uart_AO {
+ status = "okay";
+ pinctrl-0 = <&uart_ao_a_pins>;
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,215 @@
+From fece5cdfd0a0be48e8b78294fc9242216761d13e Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Sat, 27 Nov 2021 13:50:06 +0000
+Subject: [PATCH 45/73] WIP: arm64: dts: meson: add Headphone output to Beelink
+ GT-King
+
+Add support for the Headphone audio DAC built-in to the S922X chip.
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ .../boot/dts/amlogic/meson-g12b-gtking.dts | 120 +++++++++++++++++-
+ 1 file changed, 113 insertions(+), 7 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-gtking.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-gtking.dts
+index 5d96c1449050..a441975cbfb0 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-g12b-gtking.dts
++++ b/arch/arm64/boot/dts/amlogic/meson-g12b-gtking.dts
+@@ -8,6 +8,7 @@
+ /dts-v1/;
+
+ #include "meson-g12b-w400.dtsi"
++#include <dt-bindings/sound/meson-g12a-toacodec.h>
+ #include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+ / {
+@@ -29,14 +30,37 @@
+ sound {
+ compatible = "amlogic,axg-sound-card";
+ model = "GTKING";
+- audio-aux-devs = <&tdmout_b>;
++ audio-widgets = "Line", "Lineout";
++ audio-aux-devs = <&tdmout_b>, <&tdmout_c>,
++ <&tdmin_a>, <&tdmin_b>, <&tdmin_c>;
+ audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
+ "TDMOUT_B IN 1", "FRDDR_B OUT 1",
+ "TDMOUT_B IN 2", "FRDDR_C OUT 1",
+ "TDM_B Playback", "TDMOUT_B OUT",
++ "TDMOUT_C IN 0", "FRDDR_A OUT 2",
++ "TDMOUT_C IN 1", "FRDDR_B OUT 2",
++ "TDMOUT_C IN 2", "FRDDR_C OUT 2",
++ "TDM_C Playback", "TDMOUT_C OUT",
++ "TDMIN_A IN 4", "TDM_B Loopback",
++ "TDMIN_B IN 4", "TDM_B Loopback",
++ "TDMIN_C IN 4", "TDM_B Loopback",
++ "TDMIN_A IN 5", "TDM_C Loopback",
++ "TDMIN_B IN 5", "TDM_C Loopback",
++ "TDMIN_C IN 5", "TDM_C Loopback",
++ "TODDR_A IN 0", "TDMIN_A OUT",
++ "TODDR_B IN 0", "TDMIN_A OUT",
++ "TODDR_C IN 0", "TDMIN_A OUT",
++ "TODDR_A IN 1", "TDMIN_B OUT",
++ "TODDR_B IN 1", "TDMIN_B OUT",
++ "TODDR_C IN 1", "TDMIN_B OUT",
++ "TODDR_A IN 2", "TDMIN_C OUT",
++ "TODDR_B IN 2", "TDMIN_C OUT",
++ "TODDR_C IN 2", "TDMIN_C OUT",
+ "SPDIFOUT IN 0", "FRDDR_A OUT 3",
+ "SPDIFOUT IN 1", "FRDDR_B OUT 3",
+- "SPDIFOUT IN 2", "FRDDR_C OUT 3";
++ "SPDIFOUT IN 2", "FRDDR_C OUT 3",
++ "Lineout", "ACODEC LOLP",
++ "Lineout", "ACODEC LORP";
+
+ assigned-clocks = <&clkc CLKID_MPLL2>,
+ <&clkc CLKID_MPLL0>,
+@@ -59,8 +83,20 @@
+ sound-dai = <&frddr_c>;
+ };
+
+- /* 8ch hdmi interface */
+ 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_b>;
+ dai-format = "i2s";
+ dai-tdm-slot-tx-mask-0 = <1 1>;
+@@ -69,13 +105,17 @@
+ dai-tdm-slot-tx-mask-3 = <1 1>;
+ mclk-fs = <256>;
+
+- codec {
++ codec-0 {
+ sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
+ };
++
++ codec-1 {
++ sound-dai = <&toacodec TOACODEC_IN_B>;
++ };
+ };
+
+ /* spdif hdmi or toslink interface */
+- dai-link-4 {
++ dai-link-7 {
+ sound-dai = <&spdifout>;
+
+ codec-0 {
+@@ -88,7 +128,7 @@
+ };
+
+ /* spdif hdmi interface */
+- dai-link-5 {
++ dai-link-8 {
+ sound-dai = <&spdifout_b>;
+
+ codec {
+@@ -96,17 +136,47 @@
+ };
+ };
+
++ /* i2s jack output interface */
++ dai-link-9 {
++ sound-dai = <&tdmif_c>;
++ dai-format = "i2s";
++ dai-tdm-slot-tx-mask-0 = <1 1>;
++ mclk-fs = <256>;
++
++ codec-0 {
++ sound-dai = <&tohdmitx TOHDMITX_I2S_IN_C>;
++ };
++
++ codec-1 {
++ sound-dai = <&toacodec TOACODEC_IN_C>;
++ };
++ };
++
+ /* hdmi glue */
+- dai-link-6 {
++ dai-link-10 {
+ sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+ codec {
+ sound-dai = <&hdmi_tx>;
+ };
+ };
++
++ /* acodec glue */
++ dai-link-11 {
++ sound-dai = <&toacodec TOACODEC_OUT>;
++
++ codec {
++ sound-dai = <&acodec>;
++ };
++ };
+ };
+ };
+
++&acodec {
++ AVDD-supply = <&vddao_1v8>;
++ status = "okay";
++};
++
+ &arb {
+ status = "okay";
+ };
+@@ -154,10 +224,46 @@
+ status = "okay";
+ };
+
++&tdmif_c {
++ status = "okay";
++};
++
++&tdmin_a {
++ status = "okay";
++};
++
++&tdmin_b {
++ status = "okay";
++};
++
++&tdmin_c {
++ status = "okay";
++};
++
+ &tdmout_b {
+ status = "okay";
+ };
+
++&tdmout_c {
++ status = "okay";
++};
++
++&toacodec {
++ status = "okay";
++};
++
++&toddr_a {
++ status = "okay";
++};
++
++&toddr_b {
++ status = "okay";
++};
++
++&toddr_c {
++ status = "okay";
++};
++
+ &tohdmitx {
+ status = "okay";
+ };
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,29 @@
+From 363f2d99c9a9f49cabbef2818edb4df61a3f86cf Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Sat, 29 Feb 2020 15:13:02 +0000
+Subject: [PATCH 46/73] WIP: dt-bindings: arm: amlogic: add support for the
+ Tanix TX5 Max
+
+The Oranth (Tanix) TX5 Max is based on the Amlogic U200 reference
+board with an S905X2 chip.
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ Documentation/devicetree/bindings/arm/amlogic.yaml | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
+index ea4f016082c4..ba74854cd6b1 100644
+--- a/Documentation/devicetree/bindings/arm/amlogic.yaml
++++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
+@@ -145,6 +145,7 @@ properties:
+ - enum:
+ - amediatech,x96-max
+ - amlogic,u200
++ - oranth,tx5-max
+ - radxa,zero
+ - seirobotics,sei510
+ - const: amlogic,g12a
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,529 @@
+From b12f0b01cc049a365480902807c6a1db0980f587 Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Sun, 20 Oct 2019 04:06:59 +0000
+Subject: [PATCH 47/73] WIP: arm64: dts: meson: add support for the Tanix TX5
+ Max
+
+The Tanix TX5 Max is based on the Amlogic U200 reference design
+using the S905X2 chipset. Hardware specification:
+
+- 4GB LPDDR4 RAM
+- 32GB eMMC storage
+- 10/100/1000 Base-T Ethernet using External RGMII PHY
+- 802.11 a/b/g/b/ac + BT 4.1 sdio wireless
+- HDMI 2.0 (4k@60p) video
+- Composite video + 2-channel audio output on 3.5mm jack
+- S/PDIF audio output
+- 1x USB 3.0
+- 1x USB 2.0
+- 1x micro SD card slot
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ arch/arm64/boot/dts/amlogic/Makefile | 1 +
+ .../dts/amlogic/meson-g12a-tanix-tx5max.dts | 481 ++++++++++++++++++
+ 2 files changed, 482 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/amlogic/meson-g12a-tanix-tx5max.dts
+
+diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
+index 5eaaeb620a17..51a3b84bda1e 100644
+--- a/arch/arm64/boot/dts/amlogic/Makefile
++++ b/arch/arm64/boot/dts/amlogic/Makefile
+@@ -4,6 +4,7 @@ dtb-$(CONFIG_ARCH_MESON) += meson-axg-jethome-jethub-j100.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-axg-s400.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-g12a-radxa-zero.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-g12a-sei510.dtb
++dtb-$(CONFIG_ARCH_MESON) += meson-g12a-tanix-tx5max.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-g12a-u200.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-g12a-x96-max.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-g12b-a311d-khadas-vim3.dtb
+diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-tanix-tx5max.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-tanix-tx5max.dts
+new file mode 100644
+index 000000000000..0e55427ca398
+--- /dev/null
++++ b/arch/arm64/boot/dts/amlogic/meson-g12a-tanix-tx5max.dts
+@@ -0,0 +1,481 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++/*
++ * Copyright (c) 2018 BayLibre SAS. All rights reserved.
++ */
++
++/dts-v1/;
++
++#include "meson-g12a.dtsi"
++#include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/gpio/meson-g12a-gpio.h>
++#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
++
++/ {
++ compatible = "oranth,tx5-max", "amlogic,g12a";
++ model = "Tanix TX5 Max";
++
++ aliases {
++ serial0 = &uart_AO;
++ ethernet0 = ðmac;
++ };
++
++ spdif_dit: audio-codec-1 {
++ #sound-dai-cells = <0>;
++ compatible = "linux,spdif-dit";
++ status = "okay";
++ sound-name-prefix = "DIT";
++ };
++
++ chosen {
++ stdout-path = "serial0:115200n8";
++ };
++ memory@0 {
++ device_type = "memory";
++ reg = <0x0 0x0 0x0 0x40000000>;
++ };
++
++ cvbs-connector {
++ compatible = "composite-video-connector";
++
++ port {
++ cvbs_connector_in: endpoint {
++ remote-endpoint = <&cvbs_vdac_out>;
++ };
++ };
++ };
++
++ hdmi-connector {
++ compatible = "hdmi-connector";
++ type = "a";
++
++ port {
++ hdmi_connector_in: endpoint {
++ remote-endpoint = <&hdmi_tx_tmds_out>;
++ };
++ };
++ };
++
++ emmc_pwrseq: emmc-pwrseq {
++ compatible = "mmc-pwrseq-emmc";
++ reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>;
++ };
++
++ sdio_pwrseq: sdio-pwrseq {
++ compatible = "mmc-pwrseq-simple";
++ reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
++ clocks = <&wifi32k>;
++ clock-names = "ext_clock";
++ };
++
++ flash_1v8: regulator-flash_1v8 {
++ compatible = "regulator-fixed";
++ regulator-name = "FLASH_1V8";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ vin-supply = <&vcc_3v3>;
++ regulator-always-on;
++ };
++
++ dc_in: regulator-dc_in {
++ compatible = "regulator-fixed";
++ regulator-name = "DC_IN";
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ regulator-always-on;
++ };
++
++ vcc_1v8: regulator-vcc_1v8 {
++ compatible = "regulator-fixed";
++ regulator-name = "VCC_1V8";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ vin-supply = <&vcc_3v3>;
++ regulator-always-on;
++ };
++
++ vcc_3v3: regulator-vcc_3v3 {
++ compatible = "regulator-fixed";
++ regulator-name = "VCC_3V3";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ vin-supply = <&vddao_3v3>;
++ regulator-always-on;
++ /* FIXME: actually controlled by VDDCPU_B_EN */
++ };
++
++ vcc_5v: regulator-vcc_5v {
++ compatible = "regulator-fixed";
++ regulator-name = "VCC_5V";
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ vin-supply = <&dc_in>;
++
++ gpio = <&gpio GPIOH_8 GPIO_OPEN_DRAIN>;
++ enable-active-low;
++ };
++
++ vddao_1v8: regulator-vddao_1v8 {
++ compatible = "regulator-fixed";
++ regulator-name = "VDDAO_1V8";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ vin-supply = <&vddao_3v3>;
++ regulator-always-on;
++ };
++
++ vddao_3v3: regulator-vddao_3v3 {
++ compatible = "regulator-fixed";
++ regulator-name = "VDDAO_3V3";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ vin-supply = <&dc_in>;
++ regulator-always-on;
++ };
++
++ vddcpu: regulator-vddcpu {
++ compatible = "pwm-regulator";
++
++ regulator-name = "VDDCPU";
++ regulator-min-microvolt = <721000>;
++ regulator-max-microvolt = <1022000>;
++
++ vin-supply = <&dc_in>;
++
++ pwms = <&pwm_AO_cd 1 1250 0>;
++ pwm-dutycycle-range = <100 0>;
++
++ regulator-boot-on;
++ regulator-always-on;
++ };
++
++ wifi32k: wifi32k {
++ compatible = "pwm-clock";
++ #clock-cells = <0>;
++ clock-frequency = <32768>;
++ pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */
++ };
++
++ sound {
++ compatible = "amlogic,axg-sound-card";
++ model = "TANIX-TX5MAX";
++ audio-aux-devs = <&tdmout_b>;
++ audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
++ "TDMOUT_B IN 1", "FRDDR_B OUT 1",
++ "TDMOUT_B IN 2", "FRDDR_C OUT 1",
++ "TDM_B Playback", "TDMOUT_B OUT",
++ "SPDIFOUT IN 0", "FRDDR_A OUT 3",
++ "SPDIFOUT IN 1", "FRDDR_B OUT 3",
++ "SPDIFOUT IN 2", "FRDDR_C OUT 3";
++
++ assigned-clocks = <&clkc CLKID_MPLL2>,
++ <&clkc CLKID_MPLL0>,
++ <&clkc CLKID_MPLL1>;
++ assigned-clock-parents = <0>, <0>, <0>;
++ assigned-clock-rates = <294912000>,
++ <270950400>,
++ <393216000>;
++ status = "okay";
++
++ dai-link-0 {
++ sound-dai = <&frddr_a>;
++ };
++
++ dai-link-1 {
++ sound-dai = <&frddr_b>;
++ };
++
++ dai-link-2 {
++ sound-dai = <&frddr_c>;
++ };
++
++ /* 8ch hdmi interface */
++ dai-link-3 {
++ sound-dai = <&tdmif_b>;
++ dai-format = "i2s";
++ dai-tdm-slot-tx-mask-0 = <1 1>;
++ dai-tdm-slot-tx-mask-1 = <1 1>;
++ dai-tdm-slot-tx-mask-2 = <1 1>;
++ dai-tdm-slot-tx-mask-3 = <1 1>;
++ mclk-fs = <256>;
++
++ codec {
++ sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
++ };
++ };
++
++ /* spdif hdmi or toslink interface */
++ dai-link-4 {
++ sound-dai = <&spdifout>;
++
++ codec-0 {
++ sound-dai = <&spdif_dit>;
++ };
++
++ codec-1 {
++ sound-dai = <&tohdmitx TOHDMITX_SPDIF_IN_A>;
++ };
++ };
++
++ /* spdif hdmi interface */
++ dai-link-5 {
++ sound-dai = <&spdifout_b>;
++
++ codec {
++ sound-dai = <&tohdmitx TOHDMITX_SPDIF_IN_B>;
++ };
++ };
++
++ /* hdmi glue */
++ dai-link-6 {
++ sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
++
++ codec {
++ sound-dai = <&hdmi_tx>;
++ };
++ };
++ };
++};
++
++&arb {
++ status = "okay";
++};
++
++&cec_AO {
++ pinctrl-0 = <&cec_ao_a_h_pins>;
++ pinctrl-names = "default";
++ status = "disabled";
++ hdmi-phandle = <&hdmi_tx>;
++};
++
++&cecb_AO {
++ pinctrl-0 = <&cec_ao_b_h_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++ hdmi-phandle = <&hdmi_tx>;
++};
++
++&clkc_audio {
++ status = "okay";
++};
++
++&cpu0 {
++ cpu-supply = <&vddcpu>;
++ operating-points-v2 = <&cpu_opp_table>;
++ clocks = <&clkc CLKID_CPU_CLK>;
++ clock-latency = <50000>;
++};
++
++&cpu1 {
++ cpu-supply = <&vddcpu>;
++ operating-points-v2 = <&cpu_opp_table>;
++ clocks = <&clkc CLKID_CPU_CLK>;
++ clock-latency = <50000>;
++};
++
++&cpu2 {
++ cpu-supply = <&vddcpu>;
++ operating-points-v2 = <&cpu_opp_table>;
++ clocks = <&clkc CLKID_CPU_CLK>;
++ clock-latency = <50000>;
++};
++
++&cpu3 {
++ cpu-supply = <&vddcpu>;
++ operating-points-v2 = <&cpu_opp_table>;
++ clocks = <&clkc CLKID_CPU_CLK>;
++ clock-latency = <50000>;
++};
++
++&cvbs_vdac_port {
++ cvbs_vdac_out: endpoint {
++ remote-endpoint = <&cvbs_connector_in>;
++ };
++};
++
++&frddr_a {
++ status = "okay";
++};
++
++&frddr_b {
++ status = "okay";
++};
++
++&frddr_c {
++ status = "okay";
++};
++
++&hdmi_tx {
++ status = "okay";
++ pinctrl-0 = <&hdmitx_hpd_pins>, <&hdmitx_ddc_pins>;
++ pinctrl-names = "default";
++ hdmi-supply = <&vcc_5v>;
++};
++
++&hdmi_tx_tmds_port {
++ hdmi_tx_tmds_out: endpoint {
++ remote-endpoint = <&hdmi_connector_in>;
++ };
++};
++
++&ir {
++ status = "okay";
++ pinctrl-0 = <&remote_input_ao_pins>;
++ pinctrl-names = "default";
++ linux,rc-map-name = "rc-tx5max";
++};
++
++&pwm_AO_cd {
++ pinctrl-0 = <&pwm_ao_d_e_pins>;
++ pinctrl-names = "default";
++ clocks = <&xtal>;
++ clock-names = "clkin1";
++ status = "okay";
++};
++
++&ext_mdio {
++ external_phy: ethernet-phy@0 {
++ /* Realtek RTL8211F (0x001cc916) */
++ reg = <0>;
++ max-speed = <1000>;
++ eee-broken-1000t;
++
++ reset-assert-us = <10000>;
++ reset-deassert-us = <80000>;
++ reset-gpios = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
++
++ interrupt-parent = <&gpio_intc>;
++ /* MAC_INTR on GPIOZ_14 */
++ interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
++ };
++};
++
++ðmac {
++ pinctrl-0 = <ð_pins>, <ð_rgmii_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++ phy-mode = "rgmii";
++ phy-handle = <&external_phy>;
++ amlogic,tx-delay-ns = <2>;
++};
++
++&pwm_ef {
++ status = "okay";
++ pinctrl-0 = <&pwm_e_pins>;
++ pinctrl-names = "default";
++ clocks = <&xtal>;
++ clock-names = "clkin0";
++};
++
++&uart_A {
++ status = "okay";
++ pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>;
++ pinctrl-names = "default";
++ uart-has-rtscts;
++
++ bluetooth {
++ compatible = "brcm,bcm43438-bt";
++ shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
++ max-speed = <2000000>;
++ clocks = <&wifi32k>;
++ clock-names = "lpo";
++ };
++};
++
++&uart_AO {
++ status = "okay";
++ pinctrl-0 = <&uart_ao_a_pins>;
++ pinctrl-names = "default";
++};
++
++&usb {
++ status = "okay";
++ dr_mode = "host";
++};
++
++/* SDIO */
++&sd_emmc_a {
++ status = "okay";
++ pinctrl-0 = <&sdio_pins>;
++ pinctrl-1 = <&sdio_clk_gate_pins>;
++ pinctrl-names = "default", "clk-gate";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ bus-width = <4>;
++ cap-sd-highspeed;
++ sd-uhs-sdr50;
++ max-frequency = <100000000>;
++
++ non-removable;
++ disable-wp;
++
++ /* WiFi firmware requires power to be kept while in suspend */
++ keep-power-in-suspend;
++
++ mmc-pwrseq = <&sdio_pwrseq>;
++
++ vmmc-supply = <&vddao_3v3>;
++ vqmmc-supply = <&vddao_1v8>;
++
++ brcmf: wifi@1 {
++ reg = <1>;
++ compatible = "brcm,bcm4329-fmac";
++ };
++};
++
++/* SD card */
++&sd_emmc_b {
++ status = "okay";
++ pinctrl-0 = <&sdcard_c_pins>;
++ pinctrl-1 = <&sdcard_clk_gate_c_pins>;
++ pinctrl-names = "default", "clk-gate";
++
++ bus-width = <4>;
++ cap-sd-highspeed;
++ max-frequency = <100000000>;
++ disable-wp;
++
++ cd-gpios = <&gpio GPIOC_6 GPIO_ACTIVE_LOW>;
++ vmmc-supply = <&vddao_3v3>;
++ vqmmc-supply = <&vddao_3v3>;
++};
++
++/* eMMC */
++&sd_emmc_c {
++ status = "okay";
++ pinctrl-0 = <&emmc_ctrl_pins>, <&emmc_data_8b_pins>, <&emmc_ds_pins>;
++ pinctrl-1 = <&emmc_clk_gate_pins>;
++ pinctrl-names = "default", "clk-gate";
++
++ bus-width = <8>;
++ cap-mmc-highspeed;
++ max-frequency = <100000000>;
++ non-removable;
++ disable-wp;
++
++ mmc-pwrseq = <&emmc_pwrseq>;
++ vmmc-supply = <&vcc_3v3>;
++ vqmmc-supply = <&flash_1v8>;
++};
++
++&spdifout {
++ pinctrl-0 = <&spdif_out_h_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++};
++
++&spdifout_b {
++ status = "okay";
++};
++
++&tdmif_b {
++ status = "okay";
++};
++
++&tdmout_b {
++ status = "okay";
++};
++
++&tohdmitx {
++ status = "okay";
++};
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,215 @@
+From 9246eb3763b8fc6837b6041cd6c1441fcf12eddc Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Mon, 21 Oct 2019 03:58:06 +0000
+Subject: [PATCH 48/73] WIP: arm64: dts: meson: add multiple MeCool device
+ trees
+
+This adds initial device trees for a range of MeCool devices based on various
+Amlogic GXBB, GXL and GXM reference designs. The current purpose is to allow
+devices to be associated with their respective IR remote keymaps. It also
+prepares for the addition of DVB support in the future.
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ arch/arm64/boot/dts/amlogic/Makefile | 11 ++++++
+ .../dts/amlogic/meson-gxbb-mecool-ki-plus.dts | 34 +++++++++++++++++++
+ .../dts/amlogic/meson-gxbb-mecool-kii-pro.dts | 34 +++++++++++++++++++
+ .../meson-gxl-s905d-mecool-ki-plus.dts | 21 ++++++++++++
+ .../amlogic/meson-gxl-s905d-mecool-ki-pro.dts | 16 +++++++++
+ .../meson-gxl-s905d-mecool-m8s-plus.dts | 16 +++++++++
+ 6 files changed, 132 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/amlogic/meson-gxbb-mecool-ki-plus.dts
+ create mode 100644 arch/arm64/boot/dts/amlogic/meson-gxbb-mecool-kii-pro.dts
+ create mode 100644 arch/arm64/boot/dts/amlogic/meson-gxl-s905d-mecool-ki-plus.dts
+ create mode 100644 arch/arm64/boot/dts/amlogic/meson-gxl-s905d-mecool-ki-pro.dts
+ create mode 100644 arch/arm64/boot/dts/amlogic/meson-gxl-s905d-mecool-m8s-plus.dts
+
+diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
+index 51a3b84bda1e..1caed487c074 100644
+--- a/arch/arm64/boot/dts/amlogic/Makefile
++++ b/arch/arm64/boot/dts/amlogic/Makefile
+@@ -17,6 +17,8 @@ dtb-$(CONFIG_ARCH_MESON) += meson-g12b-radxa-zero2.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-g12b-s922x-khadas-vim3.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-g12b-ugoos-am6.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-kii-pro.dtb
++dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-mecool-ki-plus.dtb
++dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-mecool-kii-pro.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-nanopi-k2.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-nexbox-a95x.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-odroidc2.dtb
+@@ -30,12 +32,21 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-wetek-play2.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s805x-libretech-ac.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s805x-p241.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-libretech-pc.dtb
++dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-mecool-ki-plus.dtb
++dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-mecool-ki-pro.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-mecool-kii-pro.dtb
++dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-mecool-m8s-plus.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-p230.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-p231.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-phicomm-n1.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-sml5442tw.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-vero4k-plus.dtb
++dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-hwacom-amazetv.dtb
++dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-khadas-vim.dtb
++dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-libretech-cc.dtb
++dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-libretech-cc-v2.dtb
++dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-nexbox-a95x.dtb
++dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-p212.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905w-jethome-jethub-j80.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905w-p281.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905w-tx3-mini.dtb
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-mecool-ki-plus.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-mecool-ki-plus.dts
+new file mode 100644
+index 000000000000..cb422633a8f9
+--- /dev/null
++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-mecool-ki-plus.dts
+@@ -0,0 +1,34 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++
++/*
++ * Author: Christian Hewitt <christianshewitt@gmail.com>
++ */
++
++#include "meson-gxbb-p201.dts"
++
++/ {
++ compatible = "videostrong,gxbb-ki-plus", "amlogic,meson-gxbb";
++ model = "MeCool KI Plus";
++
++ clock: meson_clock {
++ compatible = "amlogic, gxbb-clock";
++ reg = <0x0 0xc883c000 0x0 0x1000>,
++ <0x0 0xc8100000 0x0 0x1000>;
++ #clock-cells = <1>;
++ #reset-cells = <1>;
++ sys_max = <1536000000>;
++ };
++
++ memory@0 {
++ device_type = "memory";
++ reg = <0x0 0x0 0x0 0x40000000>;
++ };
++};
++
++&ir {
++ linux,rc-map-name = "rc-mecool-ki-plus";
++};
++
++&usb_pwr {
++ gpio = <>;
++};
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-mecool-kii-pro.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-mecool-kii-pro.dts
+new file mode 100644
+index 000000000000..0dbcf0f7dbd9
+--- /dev/null
++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-mecool-kii-pro.dts
+@@ -0,0 +1,34 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++
++/*
++ * Author: Christian Hewitt <christianshewitt@gmail.com>
++ */
++
++#include "meson-gxbb-p201.dts"
++
++/ {
++ compatible = "videostrong,gxbb-kii-pro", "amlogic,meson-gxbb";
++ model = "MeCool KII Pro";
++
++ clock: meson_clock {
++ compatible = "amlogic, gxbb-clock";
++ reg = <0x0 0xc883c000 0x0 0x1000>,
++ <0x0 0xc8100000 0x0 0x1000>;
++ #clock-cells = <1>;
++ #reset-cells = <1>;
++ sys_max = <1536000000>;
++ };
++
++ memory@0 {
++ device_type = "memory";
++ reg = <0x0 0x0 0x0 0x40000000>;
++ };
++};
++
++&ir {
++ linux,rc-map-name = "rc-mecool-kii-pro";
++};
++
++&usb_pwr {
++ gpio = <>;
++};
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-mecool-ki-plus.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-mecool-ki-plus.dts
+new file mode 100644
+index 000000000000..b4aed5d0dbdf
+--- /dev/null
++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-mecool-ki-plus.dts
+@@ -0,0 +1,21 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++
++/*
++ * Author: Christian Hewitt <christianshewitt@gmail.com>
++ */
++
++#include "meson-gxl-s905d-p231.dts"
++
++/ {
++ compatible = "videostrong,gxl-ki-plus", "amlogic,s905d", "amlogic,meson-gxl";
++ model = "MeCool KI Plus";
++
++ memory@0 {
++ device_type = "memory";
++ reg = <0x0 0x0 0x0 0x40000000>;
++ };
++};
++
++&ir {
++ linux,rc-map-name = "rc-mecool-ki-plus";
++};
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-mecool-ki-pro.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-mecool-ki-pro.dts
+new file mode 100644
+index 000000000000..af695620728c
+--- /dev/null
++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-mecool-ki-pro.dts
+@@ -0,0 +1,16 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++
++/*
++ * Author: Christian Hewitt <christianshewitt@gmail.com>
++ */
++
++#include "meson-gxl-s905d-p230.dts"
++
++/ {
++ compatible = "videostrong,gxl-ki-pro", "amlogic,s905d", "amlogic,meson-gxl";
++ model = "MeCool KI Pro";
++};
++
++&ir {
++ linux,rc-map-name = "rc-mecool-ki-pro";
++};
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-mecool-m8s-plus.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-mecool-m8s-plus.dts
+new file mode 100644
+index 000000000000..3ddcf59d2649
+--- /dev/null
++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-mecool-m8s-plus.dts
+@@ -0,0 +1,16 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++
++/*
++ * Author: Christian Hewitt <christianshewitt@gmail.com>
++ */
++
++#include "meson-gxl-s905d-p231.dts"
++
++/ {
++ compatible = "videostrong,gxl-kii-pro", "amlogic,s905d", "amlogic,meson-gxl";
++ model = "MeCool M8S Plus";
++};
++
++&ir {
++ linux,rc-map-name = "rc-mecool-m8s-plus";
++};
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,29 @@
+From a5736b0b8811d7cad0c79fde2768b6cef819e35d Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Sun, 11 Apr 2021 05:50:13 +0000
+Subject: [PATCH 49/73] WIP: dt-bindings: arm: amlogic: add support for Minix
+ NEO-U1
+
+The Minix NEO-U1 is an Android STB based on the Amlogic P200 (GXBB)
+reference design with an S905 chip.
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ Documentation/devicetree/bindings/arm/amlogic.yaml | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
+index ba74854cd6b1..7e801f208863 100644
+--- a/Documentation/devicetree/bindings/arm/amlogic.yaml
++++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
+@@ -58,6 +58,7 @@ properties:
+ - amlogic,p201
+ - friendlyarm,nanopi-k2
+ - hardkernel,odroid-c2
++ - minix,neo-u1
+ - nexbox,a95x
+ - videostrong,kii-pro
+ - wetek,hub
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,241 @@
+From b2e02da33d49e72e3b3f126f6df87608be02443c Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Sun, 11 Apr 2021 05:52:14 +0000
+Subject: [PATCH 50/73] WIP: arm64: dts: meson: add initial device-tree for
+ Minix NEO-U1
+
+The Minix NEO-U1 is an Android STB based on the Amlogic P200 (GXBB)
+reference design with an S905-H chip and the following specs:
+
+- 2GB DDR3 RAM
+- 16GB eMMC
+- 10/100/1000 Base-T Ethernet
+- AP6356 Wireless (802.11 b/g/n/ac, BT 5.0)
+- HDMI 2.1 video
+- S/PDIF optical output
+- ES8323 DAC
+- 3x USB 2.0 port
+- 1x USB micro OTG port
+- RTC chip (hym8563)
+- IR receiver
+- 1x Power LED (white)
+- 1x Update/Reset button (underside)
+- 1x micro SD card slot
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ arch/arm64/boot/dts/amlogic/Makefile | 1 +
+ .../dts/amlogic/meson-gxbb-minix-neo-u1.dts | 189 ++++++++++++++++++
+ 2 files changed, 190 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/amlogic/meson-gxbb-minix-neo-u1.dts
+
+diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
+index 1caed487c074..fd0d7d68f8e6 100644
+--- a/arch/arm64/boot/dts/amlogic/Makefile
++++ b/arch/arm64/boot/dts/amlogic/Makefile
+@@ -19,6 +19,7 @@ dtb-$(CONFIG_ARCH_MESON) += meson-g12b-ugoos-am6.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-kii-pro.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-mecool-ki-plus.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-mecool-kii-pro.dtb
++dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-minix-neo-u1.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-nanopi-k2.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-nexbox-a95x.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-odroidc2.dtb
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-minix-neo-u1.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-minix-neo-u1.dts
+new file mode 100644
+index 000000000000..5343e90f9f34
+--- /dev/null
++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-minix-neo-u1.dts
+@@ -0,0 +1,189 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++/*
++ * Copyright (c) 2021 Christian Hewitt <christianshewitt@gmail.com>
++ */
++
++/dts-v1/;
++
++#include "meson-gxbb-p20x.dtsi"
++#include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/input/input.h>
++#include <dt-bindings/leds/common.h>
++#include <dt-bindings/sound/meson-aiu.h>
++
++/ {
++ compatible = "minix,neo-u1", "amlogic,meson-gxbb";
++ model = "Minix NEO U1";
++
++ aliases {
++ rtc0 = &rtc;
++ };
++
++ spdif_dit: audio-codec-0 {
++ #sound-dai-cells = <0>;
++ compatible = "linux,spdif-dit";
++ status = "okay";
++ sound-name-prefix = "DIT";
++ };
++
++ leds {
++ compatible = "gpio-leds";
++
++ led-status {
++ color = <LED_COLOR_ID_WHITE>;
++ function = LED_FUNCTION_STATUS;
++ gpios = <&gpio_ao GPIOAO_13 GPIO_ACTIVE_HIGH>;
++ default-state = "on";
++ };
++ };
++
++ gpio-keys-polled {
++ compatible = "gpio-keys-polled";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ poll-interval = <20>;
++
++ button-reset {
++ label = "reset";
++ linux,code = <KEY_POWER>;
++ gpios = <&gpio_ao GPIOAO_3 GPIO_ACTIVE_HIGH>;
++ };
++ };
++
++ avdd18_usb_adc: regulator-avdd18_usb_adc {
++ compatible = "regulator-fixed";
++ regulator-name = "AVDD18_USB_ADC";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
++
++ sound {
++ compatible = "amlogic,gx-sound-card";
++ model = "MINIX-NEO";
++ assigned-clocks = <&clkc CLKID_MPLL0>,
++ <&clkc CLKID_MPLL1>,
++ <&clkc CLKID_MPLL2>;
++ assigned-clock-parents = <0>, <0>, <0>;
++ assigned-clock-rates = <294912000>,
++ <270950400>,
++ <393216000>;
++ status = "okay";
++
++ dai-link-0 {
++ sound-dai = <&aiu AIU_CPU CPU_I2S_FIFO>;
++ };
++
++ dai-link-1 {
++ sound-dai = <&aiu AIU_CPU CPU_SPDIF_FIFO>;
++ };
++
++ dai-link-2 {
++ sound-dai = <&aiu AIU_CPU CPU_I2S_ENCODER>;
++ dai-format = "i2s";
++ mclk-fs = <256>;
++
++ codec-0 {
++ sound-dai = <&aiu AIU_HDMI CTRL_I2S>;
++ };
++ };
++
++ dai-link-3 {
++ sound-dai = <&aiu AIU_CPU CPU_SPDIF_ENCODER>;
++
++ codec-0 {
++ sound-dai = <&spdif_dit>;
++ };
++ };
++
++ dai-link-4 {
++ sound-dai = <&aiu AIU_HDMI CTRL_OUT>;
++
++ codec-0 {
++ sound-dai = <&hdmi_tx>;
++ };
++ };
++ };
++};
++
++&aiu {
++ status = "okay";
++ pinctrl-0 = <&spdif_out_y_pins>;
++ pinctrl-names = "default";
++};
++
++ðmac {
++ status = "okay";
++ pinctrl-0 = <ð_rgmii_pins>;
++ pinctrl-names = "default";
++
++ phy-handle = <ð_phy0>;
++ phy-mode = "rgmii";
++
++ amlogic,tx-delay-ns = <2>;
++
++ mdio {
++ compatible = "snps,dwmac-mdio";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ eth_phy0: ethernet-phy@0 {
++ /* Realtek RTL8211F (0x001cc916) */
++ reg = <0>;
++
++ reset-assert-us = <10000>;
++ reset-deassert-us = <80000>;
++ reset-gpios = <&gpio GPIOZ_14 GPIO_ACTIVE_LOW>;
++
++ interrupt-parent = <&gpio_intc>;
++ /* MAC_INTR on GPIOZ_15 */
++ interrupts = <29 IRQ_TYPE_LEVEL_LOW>;
++ };
++ };
++};
++
++&ir {
++ linux,rc-map-name = "rc-minix-neo";
++};
++
++&i2c_A {
++ status = "okay";
++ pinctrl-0 = <&i2c_a_pins>;
++ pinctrl-names = "default";
++};
++
++&i2c_B {
++ status = "okay";
++ pinctrl-0 = <&i2c_b_pins>;
++ pinctrl-names = "default";
++
++ rtc: rtc@51 {
++ status = "okay";
++ compatible = "haoyu,hym8563";
++ reg = <0x51>;
++ #clock-cells = <0>;
++ clock-frequency = <32768>;
++ clock-output-names = "xin32k";
++ wakeup-source;
++ };
++};
++
++&saradc {
++ status = "okay";
++ vref-supply = <&avdd18_usb_adc>;
++};
++
++/* This is connected to the Bluetooth module: */
++&uart_A {
++ status = "okay";
++ pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>;
++ pinctrl-names = "default";
++ uart-has-rtscts;
++
++ bluetooth {
++ compatible = "bcm43438-bt";
++ shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
++ max-speed = <2000000>;
++ clocks = <&wifi32k>;
++ clock-names = "lpo";
++ };
++};
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,28 @@
+From c543938e8b30003ef31501248601b9cd5d15270e Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Fri, 19 Aug 2022 21:32:21 +0000
+Subject: [PATCH 51/73] LOCAL: arm64: dts: meson: add rtc/vrtc aliases to Minix
+ NEO-U1
+
+Add node aliases to prevent meson-vrtc from claiming /dev/rtc0
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ arch/arm64/boot/dts/amlogic/meson-gxbb-minix-neo-u1.dts | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-minix-neo-u1.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-minix-neo-u1.dts
+index 5343e90f9f34..5900ee92ca28 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-minix-neo-u1.dts
++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-minix-neo-u1.dts
+@@ -17,6 +17,7 @@
+
+ aliases {
+ rtc0 = &rtc;
++ rtc1 = &vrtc;
+ };
+
+ spdif_dit: audio-codec-0 {
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,117 @@
+From a85233ca2209fa517b3b68c6563f940591481501 Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Wed, 8 Dec 2021 15:33:47 +0000
+Subject: [PATCH 52/73] WIP: media: rc: add keymap for Beelink Mini MXIII
+ remote
+
+Add a keymap and bindings for the simple IR (NEC) remote used with
+the Beelink Mini MXIII Android STB device.
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ .../devicetree/bindings/media/rc.yaml | 1 +
+ drivers/media/rc/keymaps/Makefile | 1 +
+ drivers/media/rc/keymaps/rc-beelink-mxiii.c | 54 +++++++++++++++++++
+ include/media/rc-map.h | 1 +
+ 4 files changed, 57 insertions(+)
+ create mode 100644 drivers/media/rc/keymaps/rc-beelink-mxiii.c
+
+diff --git a/Documentation/devicetree/bindings/media/rc.yaml b/Documentation/devicetree/bindings/media/rc.yaml
+index b11d14ab89c4..1121006b9fbe 100644
+--- a/Documentation/devicetree/bindings/media/rc.yaml
++++ b/Documentation/devicetree/bindings/media/rc.yaml
+@@ -39,6 +39,7 @@ properties:
+ - rc-avertv-303
+ - rc-azurewave-ad-tu700
+ - rc-beelink-gs1
++ - rc-beelink-mxiii
+ - rc-behold
+ - rc-behold-columbus
+ - rc-budget-ci-old
+diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile
+index f513ff5caf4e..f3bf9878d72c 100644
+--- a/drivers/media/rc/keymaps/Makefile
++++ b/drivers/media/rc/keymaps/Makefile
+@@ -22,6 +22,7 @@ obj-$(CONFIG_RC_MAP) += \
+ rc-avertv-303.o \
+ rc-azurewave-ad-tu700.o \
+ rc-beelink-gs1.o \
++ rc-beelink-mxiii.o \
+ rc-behold-columbus.o \
+ rc-behold.o \
+ rc-budget-ci-old.o \
+diff --git a/drivers/media/rc/keymaps/rc-beelink-mxiii.c b/drivers/media/rc/keymaps/rc-beelink-mxiii.c
+new file mode 100644
+index 000000000000..09b77295e0a3
+--- /dev/null
++++ b/drivers/media/rc/keymaps/rc-beelink-mxiii.c
+@@ -0,0 +1,54 @@
++// SPDX-License-Identifier: GPL-2.0+
++//
++// Copyright (C) 2019 Christian Hewitt <christianshewitt@gmail.com>
++
++#include <media/rc-map.h>
++#include <linux/module.h>
++
++//
++// Keytable for the Beelink Mini MXIII remote control
++//
++
++static struct rc_map_table beelink_mxiii[] = {
++ { 0xb2dc, KEY_POWER },
++
++ { 0xb288, KEY_MUTE },
++ { 0xb282, KEY_HOME },
++
++ { 0xb2ca, KEY_UP },
++ { 0xb299, KEY_LEFT },
++ { 0xb2ce, KEY_OK },
++ { 0xb2c1, KEY_RIGHT },
++ { 0xb2d2, KEY_DOWN },
++
++ { 0xb2c5, KEY_MENU },
++ { 0xb29a, KEY_BACK },
++
++ { 0xb281, KEY_VOLUMEDOWN },
++ { 0xb280, KEY_VOLUMEUP },
++};
++
++static struct rc_map_list beelink_mxiii_map = {
++ .map = {
++ .scan = beelink_mxiii,
++ .size = ARRAY_SIZE(beelink_mxiii),
++ .rc_proto = RC_PROTO_NEC,
++ .name = RC_MAP_BEELINK_MXIII,
++ }
++};
++
++static int __init init_rc_map_beelink_mxiii(void)
++{
++ return rc_map_register(&beelink_mxiii_map);
++}
++
++static void __exit exit_rc_map_beelink_mxiii(void)
++{
++ rc_map_unregister(&beelink_mxiii_map);
++}
++
++module_init(init_rc_map_beelink_mxiii)
++module_exit(exit_rc_map_beelink_mxiii)
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Christian Hewitt <christianshewitt@gmail.com");
+diff --git a/include/media/rc-map.h b/include/media/rc-map.h
+index 793b54342dff..e4ddb3586d05 100644
+--- a/include/media/rc-map.h
++++ b/include/media/rc-map.h
+@@ -225,6 +225,7 @@ struct rc_map *rc_map_get(const char *name);
+ #define RC_MAP_AVERTV_303 "rc-avertv-303"
+ #define RC_MAP_AZUREWAVE_AD_TU700 "rc-azurewave-ad-tu700"
+ #define RC_MAP_BEELINK_GS1 "rc-beelink-gs1"
++#define RC_MAP_BEELINK_MXIII "rc-beelink-mxiii"
+ #define RC_MAP_BEHOLD "rc-behold"
+ #define RC_MAP_BEHOLD_COLUMBUS "rc-behold-columbus"
+ #define RC_MAP_BUDGET_CI_OLD "rc-budget-ci-old"
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,29 @@
+From 91747a7ed34a46cef82739d8d77645c281eda1cf Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Wed, 8 Dec 2021 15:28:50 +0000
+Subject: [PATCH 53/73] WIP: dt-bindings: arm: amlogic: add support for Beelink
+ Mini MXIII
+
+The Beelink Mini MXIII is an Android STB based on the Amlogic P200
+(GXBB) reference design with an S905 chip.
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ Documentation/devicetree/bindings/arm/amlogic.yaml | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
+index 7e801f208863..096c3cfadeb0 100644
+--- a/Documentation/devicetree/bindings/arm/amlogic.yaml
++++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
+@@ -56,6 +56,7 @@ properties:
+ - enum:
+ - amlogic,p200
+ - amlogic,p201
++ - beelink,mini-mxiii
+ - friendlyarm,nanopi-k2
+ - hardkernel,odroid-c2
+ - minix,neo-u1
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,209 @@
+From 242be8590b9bb9462c4cced8613f0a7fb141f62d Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Wed, 8 Dec 2021 15:26:00 +0000
+Subject: [PATCH 54/73] WIP: arm64: dts: meson: add support for Beelink Mini
+ MXIII
+
+This is a GXBB board that ships in two variants, one with
+a Broadcom SDIO module, and a second with RTL8723BS.
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ arch/arm64/boot/dts/amlogic/Makefile | 1 +
+ .../amlogic/meson-gxbb-beelink-mini-mxiii.dts | 172 ++++++++++++++++++
+ 2 files changed, 173 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/amlogic/meson-gxbb-beelink-mini-mxiii.dts
+
+diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
+index fd0d7d68f8e6..2fb679aa6105 100644
+--- a/arch/arm64/boot/dts/amlogic/Makefile
++++ b/arch/arm64/boot/dts/amlogic/Makefile
+@@ -17,6 +17,7 @@ dtb-$(CONFIG_ARCH_MESON) += meson-g12b-radxa-zero2.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-g12b-s922x-khadas-vim3.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-g12b-ugoos-am6.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-kii-pro.dtb
++dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-beelink-mini-mxiii.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-mecool-ki-plus.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-mecool-kii-pro.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-minix-neo-u1.dtb
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-beelink-mini-mxiii.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-beelink-mini-mxiii.dts
+new file mode 100644
+index 000000000000..3d99ca93e1d5
+--- /dev/null
++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-beelink-mini-mxiii.dts
+@@ -0,0 +1,172 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++/*
++ * Copyright (c) 2021 Christian Hewitt <christianshewitt@gmail.com>
++ */
++
++/dts-v1/;
++
++#include "meson-gxbb-p20x.dtsi"
++#include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/input/input.h>
++#include <dt-bindings/leds/common.h>
++#include <dt-bindings/sound/meson-aiu.h>
++
++/ {
++ compatible = "beelink,mini-mxiii", "amlogic,meson-gxbb";
++ model = "Beelink Mini MXIII";
++
++ spdif_dit: audio-codec-0 {
++ #sound-dai-cells = <0>;
++ compatible = "linux,spdif-dit";
++ status = "okay";
++ sound-name-prefix = "DIT";
++ };
++
++ leds {
++ compatible = "gpio-leds";
++
++ led-power {
++ /* Red in Standby */
++ color = <LED_COLOR_ID_GREEN>;
++ function = LED_FUNCTION_POWER;
++ gpios = <&gpio_ao GPIOAO_13 GPIO_ACTIVE_HIGH>;
++ default-state = "on";
++ };
++ };
++
++ gpio-keys-polled {
++ compatible = "gpio-keys-polled";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ poll-interval = <20>;
++
++ button-reset {
++ label = "reset";
++ linux,code = <KEY_POWER>;
++ gpios = <&gpio_ao GPIOAO_3 GPIO_ACTIVE_HIGH>;
++ };
++ };
++
++ avdd18_usb_adc: regulator-avdd18_usb_adc {
++ compatible = "regulator-fixed";
++ regulator-name = "AVDD18_USB_ADC";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
++
++ sound {
++ compatible = "amlogic,gx-sound-card";
++ model = "MINI-MXIII";
++ assigned-clocks = <&clkc CLKID_MPLL0>,
++ <&clkc CLKID_MPLL1>,
++ <&clkc CLKID_MPLL2>;
++ assigned-clock-parents = <0>, <0>, <0>;
++ assigned-clock-rates = <294912000>,
++ <270950400>,
++ <393216000>;
++ status = "okay";
++
++ dai-link-0 {
++ sound-dai = <&aiu AIU_CPU CPU_I2S_FIFO>;
++ };
++
++ dai-link-1 {
++ sound-dai = <&aiu AIU_CPU CPU_SPDIF_FIFO>;
++ };
++
++ dai-link-2 {
++ sound-dai = <&aiu AIU_CPU CPU_I2S_ENCODER>;
++ dai-format = "i2s";
++ mclk-fs = <256>;
++
++ codec-0 {
++ sound-dai = <&aiu AIU_HDMI CTRL_I2S>;
++ };
++ };
++
++ dai-link-3 {
++ sound-dai = <&aiu AIU_CPU CPU_SPDIF_ENCODER>;
++
++ codec-0 {
++ sound-dai = <&spdif_dit>;
++ };
++ };
++
++ dai-link-4 {
++ sound-dai = <&aiu AIU_HDMI CTRL_OUT>;
++
++ codec-0 {
++ sound-dai = <&hdmi_tx>;
++ };
++ };
++ };
++};
++
++&aiu {
++ status = "okay";
++ pinctrl-0 = <&spdif_out_y_pins>;
++ pinctrl-names = "default";
++};
++
++ðmac {
++ status = "okay";
++ pinctrl-0 = <ð_rgmii_pins>;
++ pinctrl-names = "default";
++
++ phy-handle = <ð_phy0>;
++ phy-mode = "rgmii";
++
++ amlogic,tx-delay-ns = <2>;
++
++ mdio {
++ compatible = "snps,dwmac-mdio";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ eth_phy0: ethernet-phy@0 {
++ /* Realtek RTL8211F (0x001cc916) */
++ reg = <0>;
++
++ reset-assert-us = <10000>;
++ reset-deassert-us = <80000>;
++ reset-gpios = <&gpio GPIOZ_14 GPIO_ACTIVE_LOW>;
++
++ interrupt-parent = <&gpio_intc>;
++ /* MAC_INTR on GPIOZ_15 */
++ interrupts = <29 IRQ_TYPE_LEVEL_LOW>;
++ };
++ };
++};
++
++&ir {
++ linux,rc-map-name = "rc-beelink-mxiii";
++};
++
++&saradc {
++ status = "okay";
++ vref-supply = <&avdd18_usb_adc>;
++};
++
++/* Realtek Wireless SDIO Module */
++&sd_emmc_a {
++ /delete-node/ brcmf;
++
++ rtl8723bs: wifi@1 {
++ reg = <1>;
++ compatible = "realtek,rtl8723bs";
++ };
++};
++
++/* Connected to the Bluetooth module */
++&uart_A {
++ status = "okay";
++ pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>;
++ pinctrl-names = "default";
++ uart-has-rtscts;
++
++ bluetooth {
++ compatible = "realtek,rtl8723bs-bt";
++ enable-gpios = <&gpio GPIOX_20 GPIO_ACTIVE_HIGH>;
++ host-wake-gpios = <&gpio GPIOX_21 GPIO_ACTIVE_HIGH>;
++ };
++};
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,138 @@
+From e8701365b030f23a1237df631201bd99b16e4230 Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Sun, 16 Jan 2022 08:48:02 +0000
+Subject: [PATCH 55/73] WIP: media: rc: add keymap for MeCool M8S Pro W remote
+
+Add a keymap and bindings for the simple IR (NEC) remote used with
+the MeCool M8S Pro W Android STB device.
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ .../devicetree/bindings/media/rc.yaml | 1 +
+ drivers/media/rc/keymaps/Makefile | 2 +
+ .../media/rc/keymaps/rc-mecool-m8s-pro-w.c | 75 +++++++++++++++++++
+ include/media/rc-map.h | 1 +
+ 4 files changed, 79 insertions(+)
+ create mode 100644 drivers/media/rc/keymaps/rc-mecool-m8s-pro-w.c
+
+diff --git a/Documentation/devicetree/bindings/media/rc.yaml b/Documentation/devicetree/bindings/media/rc.yaml
+index 1121006b9fbe..5e3039e71312 100644
+--- a/Documentation/devicetree/bindings/media/rc.yaml
++++ b/Documentation/devicetree/bindings/media/rc.yaml
+@@ -94,6 +94,7 @@ properties:
+ - rc-manli
+ - rc-mecool-kii-pro
+ - rc-mecool-kiii-pro
++ - rc-mecool-m8s-pro-w
+ - rc-medion-x10
+ - rc-medion-x10-digitainer
+ - rc-medion-x10-or2x
+diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile
+index f3bf9878d72c..ef48a6bbeca4 100644
+--- a/drivers/media/rc/keymaps/Makefile
++++ b/drivers/media/rc/keymaps/Makefile
+@@ -75,6 +75,8 @@ obj-$(CONFIG_RC_MAP) += \
+ rc-manli.o \
+ rc-mecool-kiii-pro.o \
+ rc-mecool-kii-pro.o \
++ rc-mecool-m8s-pro-w.o \
++ rc-medion-x10.o \
+ rc-medion-x10-digitainer.o \
+ rc-medion-x10.o \
+ rc-medion-x10-or2x.o \
+diff --git a/drivers/media/rc/keymaps/rc-mecool-m8s-pro-w.c b/drivers/media/rc/keymaps/rc-mecool-m8s-pro-w.c
+new file mode 100644
+index 000000000000..9024b999d5a9
+--- /dev/null
++++ b/drivers/media/rc/keymaps/rc-mecool-m8s-pro-w.c
+@@ -0,0 +1,75 @@
++// SPDX-License-Identifier: GPL-2.0+
++//
++// Copyright (C) 2022 Christian Hewitt <christianshewitt@gmail.com>
++
++#include <media/rc-map.h>
++#include <linux/module.h>
++
++//
++// Keytable for the MeCool M8S Pro W remote control
++//
++
++static struct rc_map_table mecool_m8s_pro_w[] = {
++
++ { 0x59, KEY_POWER },
++
++ // TV CONTROLS
++
++ { 0x08, KEY_PREVIOUS },
++ { 0x0b, KEY_NEXT },
++ { 0x18, KEY_TEXT }, // INTERNET
++ { 0x19, KEY_MUTE },
++ { 0x13, KEY_VOLUMEUP },
++ { 0x17, KEY_VOLUMEDOWN },
++
++ { 0x0d, KEY_HOME },
++ { 0x05, KEY_BACK },
++
++ { 0x06, KEY_UP },
++ { 0x5a, KEY_LEFT },
++ { 0x1b, KEY_RIGHT },
++ { 0x1a, KEY_ENTER },
++ { 0x16, KEY_DOWN },
++
++ { 0x45, KEY_MENU },
++ { 0x12, KEY_CONTEXT_MENU }, // MOUSE
++
++ { 0x52, KEY_NUMERIC_1 },
++ { 0x50, KEY_NUMERIC_2 },
++ { 0x10, KEY_NUMERIC_3 },
++ { 0x56, KEY_NUMERIC_4 },
++ { 0x54, KEY_NUMERIC_5 },
++ { 0x14, KEY_NUMERIC_6 },
++ { 0x4e, KEY_NUMERIC_7 },
++ { 0x4c, KEY_NUMERIC_8 },
++ { 0x0c, KEY_NUMERIC_9 },
++ { 0x22, KEY_INFO }, // SEARCH
++ { 0x0f, KEY_NUMERIC_0 },
++ { 0x51, KEY_BACKSPACE },
++
++};
++
++static struct rc_map_list mecool_m8s_pro_w_map = {
++ .map = {
++ .scan = mecool_m8s_pro_w,
++ .size = ARRAY_SIZE(mecool_m8s_pro_w),
++ .rc_proto = RC_PROTO_NEC,
++ .name = RC_MAP_MECOOL_M8S_PRO_W,
++ }
++};
++
++static int __init init_rc_map_mecool_m8s_pro_w(void)
++{
++ return rc_map_register(&mecool_m8s_pro_w_map);
++}
++
++static void __exit exit_rc_map_mecool_m8s_pro_w(void)
++{
++ rc_map_unregister(&mecool_m8s_pro_w_map);
++}
++
++module_init(init_rc_map_mecool_m8s_pro_w)
++module_exit(exit_rc_map_mecool_m8s_pro_w)
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Christian Hewitt <christianshewitt@gmail.com");
+diff --git a/include/media/rc-map.h b/include/media/rc-map.h
+index e4ddb3586d05..9b6f09a6fd3a 100644
+--- a/include/media/rc-map.h
++++ b/include/media/rc-map.h
+@@ -281,6 +281,7 @@ struct rc_map *rc_map_get(const char *name);
+ #define RC_MAP_MANLI "rc-manli"
+ #define RC_MAP_MECOOL_KII_PRO "rc-mecool-kii-pro"
+ #define RC_MAP_MECOOL_KIII_PRO "rc-mecool-kiii-pro"
++#define RC_MAP_MECOOL_M8S_PRO_W "rc-mecool-m8s-pro-w"
+ #define RC_MAP_MEDION_X10 "rc-medion-x10"
+ #define RC_MAP_MEDION_X10_DIGITAINER "rc-medion-x10-digitainer"
+ #define RC_MAP_MEDION_X10_OR2X "rc-medion-x10-or2x"
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,29 @@
+From cac91ad1445e0da6b9f51e5e4b3d29e6bd361b7e Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Sun, 16 Jan 2022 08:15:36 +0000
+Subject: [PATCH 56/73] WIP: dt-bindings: arm: amlogic: add support for MeCool
+ M8S Pro W
+
+The MeCool M8S Pro W is an Android STB based on the Amlogic P281
+(GXL) reference design with an S905W chip.
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ Documentation/devicetree/bindings/arm/amlogic.yaml | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
+index 096c3cfadeb0..954d536f6c56 100644
+--- a/Documentation/devicetree/bindings/arm/amlogic.yaml
++++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
+@@ -89,6 +89,7 @@ properties:
+ - amlogic,p281
+ - oranth,tx3-mini
+ - jethome,jethub-j80
++ - videostrong,gxl-m8s-pro-w
+ - const: amlogic,s905w
+ - const: amlogic,meson-gxl
+
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,66 @@
+From 282f373fa348d80178c8849853bf2919d4ab7d5d Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Sun, 16 Jan 2022 08:17:41 +0000
+Subject: [PATCH 57/73] WIP: arm64: dts: meson: add support for MeCool M8S Pro
+ W
+
+MeCool M8S Pro W is an Android STB based on the Amlogic P281 (GXL)
+reference design with an S905W chip and the following specs:
+
+- 2GB DDR3 RAM
+- 16GB eMMC
+- 10/100 Base-T Ethernet
+- SSV6051P Wireless (802.11 b/g/n)
+- HDMI 2.0 video
+- 1x 3.5mm AV jack
+- 2x USB 2.0 port
+- IR receiver
+- 1x Power LED (blue)
+- 1x Update/Reset button (underside)
+- 1x micro SD card slot
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ .../meson-gxl-s905w-mecool-m8s-pro-w.dts | 30 +++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/amlogic/meson-gxl-s905w-mecool-m8s-pro-w.dts
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905w-mecool-m8s-pro-w.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905w-mecool-m8s-pro-w.dts
+new file mode 100644
+index 000000000000..a5bbe7315471
+--- /dev/null
++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905w-mecool-m8s-pro-w.dts
+@@ -0,0 +1,30 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++/*
++ * Copyright (c) 2018 Martin Blumenstingl <martin.blumenstingl@googlemail.com>.
++ * Based on meson-gxl-s905d-p231.dts:
++ * - Copyright (c) 2016 Endless Computers, Inc.
++ * Author: Carlo Caione <carlo@endlessm.com>
++ */
++
++/dts-v1/;
++
++#include "meson-gxl-s905x.dtsi"
++#include "meson-gx-p23x-q20x.dtsi"
++
++/ {
++ compatible = "videostrong,gxl-m8s-pro-w", "amlogic,s905w", "amlogic,meson-gxl";
++ model = "MeCool M8S Pro W";
++
++ memory@0 {
++ device_type = "memory";
++ reg = <0x0 0x0 0x0 0x80000000>;
++ };
++};
++
++&ir {
++ linux,rc-map-name = "rc-mecool-m8s-pro-w";
++};
++
++&usb {
++ dr_mode = "host";
++};
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,27 @@
+From f8a3f8723b9996495a87676b66ab33d2ccde6152 Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Wed, 19 Jan 2022 02:40:20 +0000
+Subject: [PATCH 58/73] WIP: dt-bindings: arm: amlogic: add Vero 4K binding
+
+Add the board binding for the OSMC Vero 4K STB device
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ Documentation/devicetree/bindings/arm/amlogic.yaml | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
+index 954d536f6c56..ef943bf50944 100644
+--- a/Documentation/devicetree/bindings/arm/amlogic.yaml
++++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
+@@ -102,6 +102,7 @@ properties:
+ - libretech,aml-s905x-cc
+ - libretech,aml-s905x-cc-v2
+ - nexbox,a95x
++ - osmc,vero4k
+ - const: amlogic,s905x
+ - const: amlogic,meson-gxl
+
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,230 @@
+From b9752455be81fbca3fad373b608b643e48f99df0 Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Wed, 19 Jan 2022 04:06:17 +0000
+Subject: [PATCH 59/73] WIP: arm64: dts: meson: add support for OSMC Vero 4K
+
+The OSMC Vero 4K device is based on the Amlogic S905X (P212) reference
+design with the following specifications:
+
+- 2GB DDR4 RAM
+- 16GB eMMC
+- HDMI 2.1 video
+- S/PDIF optical output
+- AV output
+- 10/100 Ethernet
+- AP6255 Wireless (802.11 a/b/g/n/ac, BT 4.2)
+- 2x USB 2.0 ports (1x OTG)
+- IR receiver (internal)
+- IR extender port (external)
+- 1x micro SD card slot
+- 1x Power LED (red)
+- 1x Reset button (in AV jack)
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ arch/arm64/boot/dts/amlogic/Makefile | 1 +
+ .../dts/amlogic/meson-gxl-s905x-vero4k.dts | 180 ++++++++++++++++++
+ 2 files changed, 181 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/amlogic/meson-gxl-s905x-vero4k.dts
+
+diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
+index 2fb679aa6105..de102b395dd3 100644
+--- a/arch/arm64/boot/dts/amlogic/Makefile
++++ b/arch/arm64/boot/dts/amlogic/Makefile
+@@ -49,6 +49,7 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-libretech-cc.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-libretech-cc-v2.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-nexbox-a95x.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-p212.dtb
++dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-vero4k.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905w-jethome-jethub-j80.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905w-p281.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905w-tx3-mini.dtb
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-vero4k.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-vero4k.dts
+new file mode 100644
+index 000000000000..6196153e424d
+--- /dev/null
++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-vero4k.dts
+@@ -0,0 +1,180 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++/*
++ * Author: Christian Hewitt <christianshewitt@gmail.com>
++ */
++
++/dts-v1/;
++
++#include "meson-gxl-s905x-p212.dtsi"
++#include <dt-bindings/input/input.h>
++#include <dt-bindings/leds/common.h>
++#include <dt-bindings/sound/meson-aiu.h>
++
++/ {
++ compatible = "osmc,vero4k", "amlogic,s905x", "amlogic,meson-gxl";
++ model = "OSMC Vero 4K";
++
++ reserved-memory {
++ /* 32 MiB reserved for ARM Trusted Firmware (BL32) */
++ secmon_reserved_bl32: secmon@5300000 {
++ reg = <0x0 0x05300000 0x0 0x2000000>;
++ no-map;
++ };
++ };
++
++ gpio-keys-polled {
++ compatible = "gpio-keys-polled";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ poll-interval = <20>;
++
++ button@0 {
++ label = "power";
++ linux,code = <KEY_POWER>;
++ gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_HIGH>;
++ };
++ };
++
++ leds {
++ compatible = "gpio-leds";
++
++ led-standby {
++ color = <LED_COLOR_ID_RED>;
++ function = LED_FUNCTION_POWER;
++ gpios = <&gpio GPIODV_24 GPIO_ACTIVE_LOW>;
++ default-state = "off";
++ panic-indicator;
++ };
++ };
++
++ dio2133: analog-amplifier {
++ compatible = "simple-audio-amplifier";
++ sound-name-prefix = "AU2";
++ VCC-supply = <&hdmi_5v>;
++ enable-gpios = <&gpio GPIOH_5 GPIO_ACTIVE_HIGH>;
++ };
++
++ cvbs-connector {
++ compatible = "composite-video-connector";
++
++ port {
++ cvbs_connector_in: endpoint {
++ remote-endpoint = <&cvbs_vdac_out>;
++ };
++ };
++ };
++
++ hdmi-connector {
++ compatible = "hdmi-connector";
++ type = "a";
++
++ port {
++ hdmi_connector_in: endpoint {
++ remote-endpoint = <&hdmi_tx_tmds_out>;
++ };
++ };
++ };
++
++ sound {
++ compatible = "amlogic,gx-sound-card";
++ model = "VERO4K";
++ audio-aux-devs = <&dio2133>;
++ audio-widgets = "Line", "Lineout";
++ audio-routing = "AU2 INL", "ACODEC LOLN",
++ "AU2 INR", "ACODEC LORN",
++ "Lineout", "AU2 OUTL",
++ "Lineout", "AU2 OUTR";
++ assigned-clocks = <&clkc CLKID_MPLL0>,
++ <&clkc CLKID_MPLL1>,
++ <&clkc CLKID_MPLL2>;
++ assigned-clock-parents = <0>, <0>, <0>;
++ assigned-clock-rates = <294912000>,
++ <270950400>,
++ <393216000>;
++ status = "okay";
++
++ dai-link-0 {
++ sound-dai = <&aiu AIU_CPU CPU_I2S_FIFO>;
++ };
++
++ dai-link-1 {
++ sound-dai = <&aiu AIU_CPU CPU_I2S_ENCODER>;
++ dai-format = "i2s";
++ mclk-fs = <256>;
++
++ codec-0 {
++ sound-dai = <&aiu AIU_HDMI CTRL_I2S>;
++ };
++
++ codec-1 {
++ sound-dai = <&aiu AIU_ACODEC CTRL_I2S>;
++ };
++ };
++
++ dai-link-2 {
++ sound-dai = <&aiu AIU_HDMI CTRL_OUT>;
++
++ codec-0 {
++ sound-dai = <&hdmi_tx>;
++ };
++ };
++
++ dai-link-3 {
++ sound-dai = <&aiu AIU_ACODEC CTRL_OUT>;
++
++ codec-0 {
++ sound-dai = <&acodec>;
++ };
++ };
++ };
++};
++
++&acodec {
++ AVDD-supply = <&vddio_ao18>;
++ status = "okay";
++};
++
++&aiu {
++ status = "okay";
++};
++
++&cec_AO {
++ status = "okay";
++ pinctrl-0 = <&ao_cec_pins>;
++ pinctrl-names = "default";
++ hdmi-phandle = <&hdmi_tx>;
++};
++
++&cvbs_vdac_port {
++ cvbs_vdac_out: endpoint {
++ remote-endpoint = <&cvbs_connector_in>;
++ };
++};
++
++ðmac {
++ phy-mode = "rmii";
++ phy-handle = <&internal_phy>;
++};
++
++&hdmi_tx {
++ status = "okay";
++ pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>;
++ pinctrl-names = "default";
++ hdmi-supply = <&hdmi_5v>;
++};
++
++&hdmi_tx_tmds_port {
++ hdmi_tx_tmds_out: endpoint {
++ remote-endpoint = <&hdmi_connector_in>;
++ };
++};
++
++&internal_phy {
++ pinctrl-0 = <ð_link_led_pins>, <ð_act_led_pins>;
++ pinctrl-names = "default";
++};
++
++/* This UART is brought out to the DB9 connector */
++&uart_AO {
++ status = "okay";
++};
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,37 @@
+From 595907b3cf75fd7c4e1378e2b1e0f603d6b72fd9 Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Tue, 12 Apr 2022 11:21:21 +0000
+Subject: [PATCH 60/73] WIP: arm64: dts: meson: add RTL8822CS bluetooth to
+ X96-Air
+
+Add the uart_A/bluetooth node for the RTL8822CS chip.
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ .../boot/dts/amlogic/meson-sm1-x96-air-gbit.dts | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air-gbit.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air-gbit.dts
+index 7e1a74046ba5..66e53c25bfb4 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air-gbit.dts
++++ b/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air-gbit.dts
+@@ -131,3 +131,16 @@
+ &tohdmitx {
+ status = "okay";
+ };
++
++&uart_A {
++ status = "okay";
++ pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>;
++ pinctrl-names = "default";
++ uart-has-rtscts;
++
++ bluetooth {
++ compatible = "realtek,rtl8822cs-bt";
++ enable-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
++ host-wake-gpios = <&gpio GPIOX_18 GPIO_ACTIVE_HIGH>;
++ };
++};
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,154 @@
+From 420bb2b17660a31cb5928df4cb38b8236c07db49 Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Sun, 10 Apr 2022 11:51:38 +0000
+Subject: [PATCH 61/73] WIP: media: rc: add keymap for Venz V10 remote
+
+Add a keymap and bindings for the IR (NEC) remote used with
+the Venz V10 Android STB device.
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ .../devicetree/bindings/media/rc.yaml | 1 +
+ drivers/media/rc/keymaps/Makefile | 1 +
+ drivers/media/rc/keymaps/rc-venz-v10.c | 92 +++++++++++++++++++
+ include/media/rc-map.h | 1 +
+ 4 files changed, 95 insertions(+)
+ create mode 100644 drivers/media/rc/keymaps/rc-venz-v10.c
+
+diff --git a/Documentation/devicetree/bindings/media/rc.yaml b/Documentation/devicetree/bindings/media/rc.yaml
+index 5e3039e71312..f441a35ce7f4 100644
+--- a/Documentation/devicetree/bindings/media/rc.yaml
++++ b/Documentation/devicetree/bindings/media/rc.yaml
+@@ -151,6 +151,7 @@ properties:
+ - rc-videomate-tv-pvr
+ - rc-videostrong-kii-pro
+ - rc-vega-s9x
++ - rc-venz-v10
+ - rc-wetek-hub
+ - rc-wetek-play2
+ - rc-winfast
+diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile
+index ef48a6bbeca4..77d8b5a69815 100644
+--- a/drivers/media/rc/keymaps/Makefile
++++ b/drivers/media/rc/keymaps/Makefile
+@@ -128,6 +128,7 @@ obj-$(CONFIG_RC_MAP) += \
+ rc-twinhan1027.o \
+ rc-twinhan-dtv-cab-ci.o \
+ rc-vega-s9x.o \
++ rc-venz-v10.o \
+ rc-videomate-m1f.o \
+ rc-videomate-s350.o \
+ rc-videomate-tv-pvr.o \
+diff --git a/drivers/media/rc/keymaps/rc-venz-v10.c b/drivers/media/rc/keymaps/rc-venz-v10.c
+new file mode 100644
+index 000000000000..f0a99a31a1d7
+--- /dev/null
++++ b/drivers/media/rc/keymaps/rc-venz-v10.c
+@@ -0,0 +1,92 @@
++// SPDX-License-Identifier: GPL-2.0+
++//
++// Copyright (C) 2022 Christian Hewitt <christianshewitt@gmail.com>
++
++#include <media/rc-map.h>
++#include <linux/module.h>
++
++//
++// Keytable for the Venz V10 remote control
++//
++
++static struct rc_map_table venz_v10[] = {
++ { 0x847912, KEY_POWER },
++ { 0x847903, KEY_MUTE },
++
++ { 0x847921, KEY_EPG },
++ { 0x847922, KEY_ZOOMIN },
++ { 0x847923, KEY_ZOOMOUT },
++ { 0x847924, KEY_SCREEN }, // LAUNCHER
++
++ // UP
++ // DOWN
++ // LEFT
++ // RIGHT
++
++ { 0x847904, KEY_FAVORITES }, // TV-SYS
++ { 0x84790a, KEY_INFO }, // RATIO
++ { 0x84791f, KEY_LANGUAGE }, // TRACK
++ { 0x84791e, KEY_SUBTITLE }, // SUB-T
++
++ { 0x847929, KEY_RED },
++ { 0x847930, KEY_GREEN },
++ { 0x847931, KEY_YELLOW },
++ { 0x847932, KEY_BLUE },
++
++ { 0x847906, KEY_HOME },
++ { 0x84791b, KEY_CONFIG },
++
++ { 0x847905, KEY_UP },
++ { 0x847907, KEY_LEFT },
++ { 0x847908, KEY_OK },
++ { 0x847909, KEY_RIGHT },
++ { 0x847900, KEY_DOWN },
++
++ { 0x847920, KEY_CONTEXT_MENU },
++ { 0x84791a, KEY_BACK },
++
++ { 0x847910, KEY_VOLUMEUP },
++ { 0x84790f, KEY_VOLUMEDOWN },
++ { 0x847919, KEY_PLAYPAUSE },
++ { 0x84791c, KEY_STOP },
++ { 0x84791d, KEY_PREVIOUS },
++ { 0x847928, KEY_NEXT },
++
++ { 0x84790b, KEY_1 },
++ { 0x84790c, KEY_2 },
++ { 0x84790d, KEY_3 },
++ { 0x84790e, KEY_4 },
++ { 0x847911, KEY_5 },
++ { 0x847927, KEY_6 },
++ { 0x847913, KEY_7 },
++ { 0x847914, KEY_8 },
++ { 0x847915, KEY_9 },
++ { 0x847916, KEY_MENU }, // MOUSE
++ { 0x847917, KEY_0 },
++ { 0x847918, KEY_DELETE },
++};
++
++static struct rc_map_list venz_v10_map = {
++ .map = {
++ .scan = venz_v10,
++ .size = ARRAY_SIZE(venz_v10),
++ .rc_proto = RC_PROTO_NEC,
++ .name = RC_MAP_VENZ_V10,
++ }
++};
++
++static int __init init_rc_map_venz_v10(void)
++{
++ return rc_map_register(&venz_v10_map);
++}
++
++static void __exit exit_rc_map_venz_v10(void)
++{
++ rc_map_unregister(&venz_v10_map);
++}
++
++module_init(init_rc_map_venz_v10)
++module_exit(exit_rc_map_venz_v10)
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Christian Hewitt <christianshewitt@gmail.com");
+diff --git a/include/media/rc-map.h b/include/media/rc-map.h
+index 9b6f09a6fd3a..43d254930daa 100644
+--- a/include/media/rc-map.h
++++ b/include/media/rc-map.h
+@@ -333,6 +333,7 @@ struct rc_map *rc_map_get(const char *name);
+ #define RC_MAP_TT_1500 "rc-tt-1500"
+ #define RC_MAP_TWINHAN_DTV_CAB_CI "rc-twinhan-dtv-cab-ci"
+ #define RC_MAP_TWINHAN_VP1027_DVBS "rc-twinhan1027"
++#define RC_MAP_VENZ_V10 "rc-venz-v10"
+ #define RC_MAP_VEGA_S9X "rc-vega-s9x"
+ #define RC_MAP_VIDEOMATE_K100 "rc-videomate-k100"
+ #define RC_MAP_VIDEOMATE_S350 "rc-videomate-s350"
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,34 @@
+From 2e6341669bc34a64c264db1137369cdb31a4ee5f Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Sat, 9 Apr 2022 06:27:50 +0000
+Subject: [PATCH 62/73] WIP: dt-bindings: arm: amlogic: add S905L and Venz V10
+ bindings
+
+Add SOC bindings for S905L devices and the board binding for Venz V10.
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ Documentation/devicetree/bindings/arm/amlogic.yaml | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
+index ef943bf50944..47a9ec09a81a 100644
+--- a/Documentation/devicetree/bindings/arm/amlogic.yaml
++++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
+@@ -83,6 +83,13 @@ properties:
+ - const: amlogic,s805x
+ - const: amlogic,meson-gxl
+
++ - description: Boards with the Amlogic Meson GXL S905L SoC
++ items:
++ - enum:
++ - venz,v10
++ - const: amlogic,s905l
++ - const: amlogic,meson-gxl
++
+ - description: Boards with the Amlogic Meson GXL S905W SoC
+ items:
+ - enum:
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,373 @@
+From 3eafb34fd8bdff426583e2fb85dfd82fb69564ca Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Sat, 9 Apr 2022 06:21:58 +0000
+Subject: [PATCH 63/73] WIP: arm64: dts: meson: add support for Venz V10
+
+The Venz V10 is an Android STB based on the Amlogic P212 (GXL)
+reference design with an S905L chip and the following specs:
+
+- 1GB DDR3 RAM
+- 8GB eMMC
+- 10/100 Base-T Ethernet
+- RTL8189ES Wireless (802.11 b/g/n)
+- HDMI 2.0b video
+- 1x 3.5mm AV jack
+- 2x USB 2.0 port
+- IR receiver
+- 1x Update/Reset button (underside)
+- 1x micro SD card slot
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ arch/arm64/boot/dts/amlogic/Makefile | 1 +
+ .../dts/amlogic/meson-gxl-s905l-venz-v10.dts | 326 ++++++++++++++++++
+ 2 files changed, 327 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/amlogic/meson-gxl-s905l-venz-v10.dts
+
+diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
+index de102b395dd3..751e1be7be1b 100644
+--- a/arch/arm64/boot/dts/amlogic/Makefile
++++ b/arch/arm64/boot/dts/amlogic/Makefile
+@@ -43,6 +43,7 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-p231.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-phicomm-n1.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-sml5442tw.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-vero4k-plus.dtb
++dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905l-venz-v10.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-hwacom-amazetv.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-khadas-vim.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-libretech-cc.dtb
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905l-venz-v10.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905l-venz-v10.dts
+new file mode 100644
+index 000000000000..553377fce051
+--- /dev/null
++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905l-venz-v10.dts
+@@ -0,0 +1,326 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++/*
++ * Copyright (c) 2016 Endless Computers, Inc.
++ * Author: Carlo Caione <carlo@endlessm.com>
++ */
++
++/dts-v1/;
++
++#include "meson-gxl-s905x.dtsi"
++#include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/leds/common.h>
++#include <dt-bindings/sound/meson-aiu.h>
++
++/ {
++ compatible = "venz,v10", "amlogic,s905l", "amlogic,meson-gxl";
++ model = "Venz V10";
++
++ aliases {
++ serial0 = &uart_AO;
++ ethernet0 = ðmac;
++ wlan0 = &rtl8189;
++ };
++
++ chosen {
++ stdout-path = "serial0:115200n8";
++ };
++
++ memory@0 {
++ device_type = "memory";
++ reg = <0x0 0x0 0x0 0x80000000>;
++ };
++
++ dio2133: analog-amplifier {
++ compatible = "simple-audio-amplifier";
++ sound-name-prefix = "AU2";
++ VCC-supply = <&hdmi_5v>;
++ enable-gpios = <&gpio GPIOH_5 GPIO_ACTIVE_HIGH>;
++ };
++
++ leds {
++ compatible = "gpio-leds";
++
++ led-standby {
++ color = <LED_COLOR_ID_BLUE>;
++ function = LED_FUNCTION_POWER;
++ gpios = <&gpio GPIODV_24 GPIO_ACTIVE_HIGH>;
++ default-state = "on";
++ };
++ };
++
++ cvbs-connector {
++ compatible = "composite-video-connector";
++
++ port {
++ cvbs_connector_in: endpoint {
++ remote-endpoint = <&cvbs_vdac_out>;
++ };
++ };
++ };
++
++ hdmi-connector {
++ compatible = "hdmi-connector";
++ type = "a";
++
++ port {
++ hdmi_connector_in: endpoint {
++ remote-endpoint = <&hdmi_tx_tmds_out>;
++ };
++ };
++ };
++
++ hdmi_5v: regulator-hdmi-5v {
++ compatible = "regulator-fixed";
++
++ regulator-name = "HDMI_5V";
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++
++ gpio = <&gpio GPIOH_3 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ regulator-always-on;
++ };
++
++ vddio_boot: regulator-vddio_boot {
++ compatible = "regulator-fixed";
++ regulator-name = "VDDIO_BOOT";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
++
++ vddao_3v3: regulator-vddao_3v3 {
++ compatible = "regulator-fixed";
++ regulator-name = "VDDAO_3V3";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ };
++
++ vddio_ao18: regulator-vddio_ao18 {
++ compatible = "regulator-fixed";
++ regulator-name = "VDDIO_AO18";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
++
++ vcc_3v3: regulator-vcc_3v3 {
++ compatible = "regulator-fixed";
++ regulator-name = "VCC_3V3";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ };
++
++ emmc_pwrseq: emmc-pwrseq {
++ compatible = "mmc-pwrseq-emmc";
++ reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
++ };
++
++ wifi32k: wifi32k {
++ compatible = "pwm-clock";
++ #clock-cells = <0>;
++ clock-frequency = <32768>;
++ pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */
++ };
++
++ sdio_pwrseq: sdio-pwrseq {
++ compatible = "mmc-pwrseq-simple";
++ reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
++ clocks = <&wifi32k>;
++ clock-names = "ext_clock";
++ };
++
++ sound {
++ compatible = "amlogic,gx-sound-card";
++ model = "VENZ-V10";
++ audio-aux-devs = <&dio2133>;
++ audio-widgets = "Line", "Lineout";
++ audio-routing = "AU2 INL", "ACODEC LOLN",
++ "AU2 INR", "ACODEC LORN",
++ "Lineout", "AU2 OUTL",
++ "Lineout", "AU2 OUTR";
++ assigned-clocks = <&clkc CLKID_MPLL0>,
++ <&clkc CLKID_MPLL1>,
++ <&clkc CLKID_MPLL2>;
++ assigned-clock-parents = <0>, <0>, <0>;
++ assigned-clock-rates = <294912000>,
++ <270950400>,
++ <393216000>;
++ status = "okay";
++
++ dai-link-0 {
++ sound-dai = <&aiu AIU_CPU CPU_I2S_FIFO>;
++ };
++
++ dai-link-1 {
++ sound-dai = <&aiu AIU_CPU CPU_I2S_ENCODER>;
++ dai-format = "i2s";
++ mclk-fs = <256>;
++
++ codec-0 {
++ sound-dai = <&aiu AIU_HDMI CTRL_I2S>;
++ };
++
++ codec-1 {
++ sound-dai = <&aiu AIU_ACODEC CTRL_I2S>;
++ };
++ };
++
++ dai-link-2 {
++ sound-dai = <&aiu AIU_HDMI CTRL_OUT>;
++
++ codec-0 {
++ sound-dai = <&hdmi_tx>;
++ };
++ };
++
++ dai-link-3 {
++ sound-dai = <&aiu AIU_ACODEC CTRL_OUT>;
++
++ codec-0 {
++ sound-dai = <&acodec>;
++ };
++ };
++ };
++};
++
++&acodec {
++ AVDD-supply = <&vddio_ao18>;
++ status = "okay";
++};
++
++&aiu {
++ status = "okay";
++};
++
++&cec_AO {
++ status = "okay";
++ pinctrl-0 = <&ao_cec_pins>;
++ pinctrl-names = "default";
++ hdmi-phandle = <&hdmi_tx>;
++};
++
++&cvbs_vdac_port {
++ cvbs_vdac_out: endpoint {
++ remote-endpoint = <&cvbs_connector_in>;
++ };
++};
++
++ðmac {
++ status = "okay";
++};
++
++&hdmi_tx {
++ status = "okay";
++ pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>;
++ pinctrl-names = "default";
++ hdmi-supply = <&hdmi_5v>;
++};
++
++&hdmi_tx_tmds_port {
++ hdmi_tx_tmds_out: endpoint {
++ remote-endpoint = <&hdmi_connector_in>;
++ };
++};
++
++&ir {
++ status = "okay";
++ pinctrl-0 = <&remote_input_ao_pins>;
++ pinctrl-names = "default";
++ linux,rc-map-name = "rc-venz-v10";
++};
++
++&pwm_ef {
++ status = "okay";
++ pinctrl-0 = <&pwm_e_pins>;
++ pinctrl-names = "default";
++ clocks = <&clkc CLKID_FCLK_DIV4>;
++ clock-names = "clkin0";
++};
++
++&saradc {
++ status = "okay";
++ vref-supply = <&vddio_ao18>;
++};
++
++/* Wireless SDIO Module */
++&sd_emmc_a {
++ status = "okay";
++ pinctrl-0 = <&sdio_pins>;
++ pinctrl-1 = <&sdio_clk_gate_pins>;
++ pinctrl-names = "default", "clk-gate";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ bus-width = <4>;
++ cap-sd-highspeed;
++ max-frequency = <100000000>;
++
++ non-removable;
++ disable-wp;
++
++ /* WiFi firmware requires power to be kept while in suspend */
++ keep-power-in-suspend;
++
++ mmc-pwrseq = <&sdio_pwrseq>;
++
++ vmmc-supply = <&vddao_3v3>;
++ vqmmc-supply = <&vddio_boot>;
++
++ rtl8189: wifi@1 {
++ reg = <1>;
++ };
++};
++
++/* SD card */
++&sd_emmc_b {
++ status = "okay";
++ pinctrl-0 = <&sdcard_pins>;
++ pinctrl-1 = <&sdcard_clk_gate_pins>;
++ pinctrl-names = "default", "clk-gate";
++
++ bus-width = <4>;
++ cap-sd-highspeed;
++ max-frequency = <50000000>;
++ disable-wp;
++
++ cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_LOW>;
++
++ vmmc-supply = <&vddao_3v3>;
++ vqmmc-supply = <&vddio_boot>;
++};
++
++/* eMMC */
++&sd_emmc_c {
++ status = "okay";
++ pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>;
++ pinctrl-1 = <&emmc_clk_gate_pins>;
++ pinctrl-names = "default", "clk-gate";
++
++ bus-width = <8>;
++ cap-mmc-highspeed;
++ max-frequency = <200000000>;
++ non-removable;
++ disable-wp;
++ mmc-ddr-1_8v;
++ mmc-hs200-1_8v;
++
++ mmc-pwrseq = <&emmc_pwrseq>;
++ vmmc-supply = <&vcc_3v3>;
++ vqmmc-supply = <&vddio_boot>;
++};
++
++/* This UART is brought out to the DB9 connector */
++&uart_AO {
++ status = "okay";
++ pinctrl-0 = <&uart_ao_a_pins>;
++ pinctrl-names = "default";
++};
++
++&usb {
++ status = "okay";
++ dr_mode = "host";
++};
++
++&usb2_phy0 {
++ /* HDMI_5V is the supply for the USB VBUS */
++ phy-supply = <&hdmi_5v>;
++};
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,29 @@
+From d36e778a5f52586b7a3bbea4ff1b17a261b222ea Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Wed, 6 Jul 2022 05:15:41 +0000
+Subject: [PATCH 64/73] WIP: dt-bindings: vendor-prefixes: add tbee prefix
+
+QUIDBox, Lda. are the Portuguese manufacturer of 'TBee' branded
+Android Set-Top Box devices.
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
+index 7163901e5976..51dc9317db26 100644
+--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
++++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
+@@ -1251,6 +1251,8 @@ patternProperties:
+ "^synopsys,.*":
+ description: Synopsys, Inc. (deprecated, use snps)
+ deprecated: true
++ "^tbee,.*":
++ description: QUIDBox Lda.
+ "^tbs,.*":
+ description: TBS Technologies
+ "^tbs-biometrics,.*":
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,27 @@
+From 747c7ac68e792e26a165b49a07cf5b05d37843e5 Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Wed, 6 Jul 2022 05:05:11 +0000
+Subject: [PATCH 65/73] WIP: dt-bindings: arm: amlogic: add TBee Box binding
+
+Add the board binding for the TBee Box.
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ Documentation/devicetree/bindings/arm/amlogic.yaml | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
+index 47a9ec09a81a..a17daa64ba31 100644
+--- a/Documentation/devicetree/bindings/arm/amlogic.yaml
++++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
+@@ -110,6 +110,7 @@ properties:
+ - libretech,aml-s905x-cc-v2
+ - nexbox,a95x
+ - osmc,vero4k
++ - tbee,box
+ - const: amlogic,s905x
+ - const: amlogic,meson-gxl
+
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,201 @@
+From 806ac3731dd4e2e35ab71c393e77e0a29f702b39 Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Wed, 6 Jul 2022 05:23:12 +0000
+Subject: [PATCH 66/73] WIP: arm64: dts: meson: add support for TBee Box
+
+The TBee Box is an Android STB based on the Amlogic P212 (GXL)
+reference design with an S905X chip and the following specs:
+
+- 2GB DDR3 RAM
+- 16GB eMMC
+- 10/100 Base-T Ethernet
+- QCA9377 Wireless (802.11 a/b/g/n, Bluetooth 4.0)
+- HDMI 2.0b video
+- 3x USB 2.0 ports
+- 1x USB WebCam (Sonix Technology)
+- IR receiver
+- 1x Update/Reset button (underside)
+- 1x Power LED (blue, front)
+- 1x SD card slot (full-size)
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ arch/arm64/boot/dts/amlogic/Makefile | 1 +
+ .../boot/dts/amlogic/meson-gxl-s905x-tbee.dts | 153 ++++++++++++++++++
+ 2 files changed, 154 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/amlogic/meson-gxl-s905x-tbee.dts
+
+diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
+index 751e1be7be1b..3e216a8e3b2a 100644
+--- a/arch/arm64/boot/dts/amlogic/Makefile
++++ b/arch/arm64/boot/dts/amlogic/Makefile
+@@ -50,6 +50,7 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-libretech-cc.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-libretech-cc-v2.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-nexbox-a95x.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-p212.dtb
++dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-tbee.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-vero4k.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905w-jethome-jethub-j80.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905w-p281.dtb
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-tbee.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-tbee.dts
+new file mode 100644
+index 000000000000..3584d87c1916
+--- /dev/null
++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-tbee.dts
+@@ -0,0 +1,153 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++/*
++ * Copyright (c) 2016 Endless Computers, Inc.
++ * Author: Carlo Caione <carlo@endlessm.com>
++ */
++
++/dts-v1/;
++
++#include "meson-gxl-s905x-p212.dtsi"
++#include <dt-bindings/sound/meson-aiu.h>
++
++/ {
++ compatible = "tbee,box", "amlogic,s905x", "amlogic,meson-gxl";
++ model = "TBee-Box";
++
++ dio2133: analog-amplifier {
++ compatible = "simple-audio-amplifier";
++ sound-name-prefix = "AU2";
++ VCC-supply = <&hdmi_5v>;
++ enable-gpios = <&gpio GPIOH_5 GPIO_ACTIVE_HIGH>;
++ };
++
++ cvbs-connector {
++ compatible = "composite-video-connector";
++
++ port {
++ cvbs_connector_in: endpoint {
++ remote-endpoint = <&cvbs_vdac_out>;
++ };
++ };
++ };
++
++ hdmi-connector {
++ compatible = "hdmi-connector";
++ type = "a";
++
++ port {
++ hdmi_connector_in: endpoint {
++ remote-endpoint = <&hdmi_tx_tmds_out>;
++ };
++ };
++ };
++
++ sound {
++ compatible = "amlogic,gx-sound-card";
++ model = "TBEE-BOX";
++ audio-aux-devs = <&dio2133>;
++ audio-widgets = "Line", "Lineout";
++ audio-routing = "AU2 INL", "ACODEC LOLN",
++ "AU2 INR", "ACODEC LORN",
++ "Lineout", "AU2 OUTL",
++ "Lineout", "AU2 OUTR";
++ assigned-clocks = <&clkc CLKID_MPLL0>,
++ <&clkc CLKID_MPLL1>,
++ <&clkc CLKID_MPLL2>;
++ assigned-clock-parents = <0>, <0>, <0>;
++ assigned-clock-rates = <294912000>,
++ <270950400>,
++ <393216000>;
++ status = "okay";
++
++ dai-link-0 {
++ sound-dai = <&aiu AIU_CPU CPU_I2S_FIFO>;
++ };
++
++ dai-link-1 {
++ sound-dai = <&aiu AIU_CPU CPU_I2S_ENCODER>;
++ dai-format = "i2s";
++ mclk-fs = <256>;
++
++ codec-0 {
++ sound-dai = <&aiu AIU_HDMI CTRL_I2S>;
++ };
++
++ codec-1 {
++ sound-dai = <&aiu AIU_ACODEC CTRL_I2S>;
++ };
++ };
++
++ dai-link-2 {
++ sound-dai = <&aiu AIU_HDMI CTRL_OUT>;
++
++ codec-0 {
++ sound-dai = <&hdmi_tx>;
++ };
++ };
++
++ dai-link-3 {
++ sound-dai = <&aiu AIU_ACODEC CTRL_OUT>;
++
++ codec-0 {
++ sound-dai = <&acodec>;
++ };
++ };
++ };
++};
++
++&acodec {
++ AVDD-supply = <&vddio_ao18>;
++ status = "okay";
++};
++
++&aiu {
++ status = "okay";
++};
++
++&cec_AO {
++ status = "okay";
++ pinctrl-0 = <&ao_cec_pins>;
++ pinctrl-names = "default";
++ hdmi-phandle = <&hdmi_tx>;
++};
++
++&cvbs_vdac_port {
++ cvbs_vdac_out: endpoint {
++ remote-endpoint = <&cvbs_connector_in>;
++ };
++};
++
++&hdmi_tx {
++ status = "okay";
++ pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>;
++ pinctrl-names = "default";
++ hdmi-supply = <&hdmi_5v>;
++};
++
++&hdmi_tx_tmds_port {
++ hdmi_tx_tmds_out: endpoint {
++ remote-endpoint = <&hdmi_connector_in>;
++ };
++};
++
++/* This is connected to the Bluetooth module: */
++&uart_A {
++ status = "okay";
++ pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>;
++ pinctrl-names = "default";
++ uart-has-rtscts;
++
++ bluetooth {
++ compatible = "qcom,qca9377-bt";
++ enable-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
++ max-speed = <2000000>;
++ clocks = <&wifi32k>;
++ clock-names = "lpo";
++ };
++};
++
++/* This UART is brought out to the DB9 connector */
++&uart_AO {
++ status = "okay";
++};
++
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,28 @@
+From ea9f2cf8516daabd388706eea334220525b0bd96 Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Sun, 24 Jul 2022 08:50:28 +0000
+Subject: [PATCH 67/73] WIP: dt-bindings: arm: amlogic: add Beelink GT1 binding
+
+Add the board binding for the Shenzen AZW (Beelink) GT1 Android
+Set-Top Box device.
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ Documentation/devicetree/bindings/arm/amlogic.yaml | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
+index a17daa64ba31..8f7908bb3fee 100644
+--- a/Documentation/devicetree/bindings/arm/amlogic.yaml
++++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
+@@ -132,6 +132,7 @@ properties:
+ - enum:
+ - amlogic,q200
+ - amlogic,q201
++ - azw,gt1
+ - azw,gt1-ultimate
+ - khadas,vim2
+ - kingnovel,r-box-pro
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,139 @@
+From 128d4f0b7fed865b7b6210cec0d7946ccca19042 Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Wed, 6 Jul 2022 10:01:03 +0000
+Subject: [PATCH 68/73] WIP: arm64: dts: meson: add support for Beelink GT1
+
+The Beelink GT1 is based on the Amlogic S912 (Q200) reference
+design with the following specifications:
+
+- 2GB DDR3 RAM
+- 16GB eMMC
+- HDMI 2.1 video
+- S/PDIF optical output
+- 10/100/1000 Ethernet
+- QCA9377 Wireless (802.11 a/b/g/n, BT 4.0)
+- 2x USB 2.0 ports
+- IR receiver (internal)
+- 1x micro SD card slot
+- 1x Power LED (white)
+- 1x Reset button (underneath)
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ arch/arm64/boot/dts/amlogic/Makefile | 1 +
+ arch/arm64/boot/dts/amlogic/meson-gxm-gt1.dts | 91 +++++++++++++++++++
+ 2 files changed, 92 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/amlogic/meson-gxm-gt1.dts
+
+diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
+index 3e216a8e3b2a..dc5167a86685 100644
+--- a/arch/arm64/boot/dts/amlogic/Makefile
++++ b/arch/arm64/boot/dts/amlogic/Makefile
+@@ -61,6 +61,7 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-libretech-cc-v2.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-libretech-cc.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-nexbox-a95x.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-p212.dtb
++dtb-$(CONFIG_ARCH_MESON) += meson-gxm-gt1.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxm-gt1-ultimate.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxm-khadas-vim2.dtb
+ dtb-$(CONFIG_ARCH_MESON) += meson-gxm-mecool-kiii-pro.dtb
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-gt1.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-gt1.dts
+new file mode 100644
+index 000000000000..3c8d73599ce6
+--- /dev/null
++++ b/arch/arm64/boot/dts/amlogic/meson-gxm-gt1.dts
+@@ -0,0 +1,91 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++/*
++ * Copyright (c) Christian Hewitt <christianshewitt@gmail.com>
++ */
++
++/dts-v1/;
++
++#include "meson-gxm.dtsi"
++#include "meson-gx-p23x-q20x.dtsi"
++#include <dt-bindings/input/input.h>
++#include <dt-bindings/leds/common.h>
++
++/ {
++ compatible = "azw,gt1", "amlogic,s912", "amlogic,meson-gxm";
++ model = "Beelink GT1";
++
++ leds {
++ compatible = "gpio-leds";
++
++ led-white {
++ color = <LED_COLOR_ID_WHITE>;
++ function = LED_FUNCTION_POWER;
++ gpios = <&gpio_ao GPIOAO_9 GPIO_ACTIVE_HIGH>;
++ default-state = "on";
++ panic-indicator;
++ };
++ };
++
++ adc-keys {
++ compatible = "adc-keys";
++ io-channels = <&saradc 0>;
++ io-channel-names = "buttons";
++ keyup-threshold-microvolt = <1710000>;
++
++ button-function {
++ label = "update";
++ linux,code = <KEY_VENDOR>;
++ press-threshold-microvolt = <10000>;
++ };
++ };
++};
++
++ðmac {
++ pinctrl-0 = <ð_pins>;
++ pinctrl-names = "default";
++ phy-handle = <&external_phy>;
++ amlogic,tx-delay-ns = <2>;
++ phy-mode = "rgmii";
++};
++
++&external_mdio {
++ external_phy: ethernet-phy@0 {
++ /* Realtek RTL8211F (0x001cc916) */
++ reg = <0>;
++ max-speed = <1000>;
++
++ reset-assert-us = <10000>;
++ reset-deassert-us = <80000>;
++ reset-gpios = <&gpio GPIOZ_14 GPIO_ACTIVE_LOW>;
++
++ interrupt-parent = <&gpio_intc>;
++ /* MAC_INTR on GPIOZ_15 */
++ interrupts = <25 IRQ_TYPE_LEVEL_LOW>;
++ };
++};
++
++&ir {
++ linux,rc-map-name = "rc-beelink-gs1";
++};
++
++&sd_emmc_a {
++ /* QCA9377 WiFi */
++ wifi: wifi@1 {
++ reg = <1>;
++ };
++};
++
++&uart_A {
++ status = "okay";
++ pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>;
++ pinctrl-names = "default";
++ uart-has-rtscts;
++
++ bluetooth {
++ compatible = "qcom,qca9377-bt";
++ shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
++ max-speed = <2000000>;
++ clocks = <&wifi32k>;
++ clock-names = "lpo";
++ };
++};
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,34 @@
+From 479af13691d399bbb6782713658a312a9800b65d Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Wed, 27 Jul 2022 10:27:10 +0000
+Subject: [PATCH 69/73] WIP: arm64: dts: meson: add vcc_5v regulator to WeTek
+ dtsi
+
+Add the vcc_5v regulator used by the audio DAC chip
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi
+index 94dafb955301..caa63f5edf03 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi
++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi
+@@ -71,6 +71,13 @@
+ regulator-always-on;
+ };
+
++ vcc_5v: regulator-vcc_5v {
++ compatible = "regulator-fixed";
++ regulator-name = "VCC_5V";
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ };
++
+ vcc_3v3: regulator-vcc_3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_3V3";
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,56 @@
+From 51142747fd8747c558922b6ef8cbbe453986c7b2 Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Wed, 27 Jul 2022 13:39:23 +0000
+Subject: [PATCH 70/73] WIP: arm64: dts: meson: add audio lineout to WeTek
+ Play2
+
+Add support for the ES7134LV headphone output on the WeTek Play2
+
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ .../boot/dts/amlogic/meson-gxbb-wetek-play2.dts | 15 ++++++++++++++-
+ 1 file changed, 14 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts
+index 505ffcd8eb76..e206d658d157 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts
++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts
+@@ -21,6 +21,13 @@
+ sound-name-prefix = "DIT";
+ };
+
++ i2s_codec: audio-codec-1 {
++ #sound-dai-cells = <0>;
++ compatible = "everest,es7134";
++ VDD-supply = <&vcc_5v>;
++ status = "okay";
++ };
++
+ leds {
+ led-wifi {
+ label = "wetek-play:wifi-status";
+@@ -74,6 +81,10 @@
+ codec-0 {
+ sound-dai = <&aiu AIU_HDMI CTRL_I2S>;
+ };
++
++ codec-1 {
++ sound-dai = <&i2s_codec>;
++ };
+ };
+
+ dai-link-3 {
+@@ -96,7 +107,9 @@
+
+ &aiu {
+ status = "okay";
+- pinctrl-0 = <&spdif_out_y_pins>;
++ pinctrl-0 = <&i2s_am_clk_pins>, <&i2s_out_ao_clk_pins>,
++ <&i2s_out_lr_clk_pins>, <&i2s_out_ch01_ao_pins>,
++ <&spdif_out_y_pins>;
+ pinctrl-names = "default";
+ };
+
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,35 @@
+From 860b75b686b8cbff5090e4db07964e51d48ed90c Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Fri, 29 Jul 2022 08:29:20 +0000
+Subject: [PATCH 71/73] WIP: arm64: dts: amlogic: fix cvbs disable on WeTek Hub
+
+The original submission in commit d537d289de06 ("ARM64: dts: meson-gxbb:
+Add support for WeTek Hub and Play") shows cvbs output as disabled, but
+this appears to have been dropped accidentally when moving WeTek boards
+to a common dtsi. The Hub does not have cvbs hardware so let's fix and
+reinstate the disable.
+
+Fixes fb72c03e0e32 ("ARM64: dts: meson-gxbb-wetek: add a wetek specific dtsi to cleanup hub and play2")
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-hub.dts | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-hub.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-hub.dts
+index 58733017eda8..23bea3fe9501 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-hub.dts
++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-hub.dts
+@@ -13,6 +13,10 @@
+ compatible = "wetek,hub", "amlogic,meson-gxbb";
+ model = "WeTek Hub";
+
++ cvbs-connector {
++ status = "disabled";
++ };
++
+ sound {
+ compatible = "amlogic,gx-sound-card";
+ model = "WETEK-HUB";
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,34 @@
+From 577af8787454fffa1a6cc387f14d564282c8b244 Mon Sep 17 00:00:00 2001
+From: Romain Perier <romain.perier@collabora.com>
+Date: Sun, 14 Aug 2022 04:21:16 +0000
+Subject: [PATCH 72/73] WIP: ASoC: dt-bindings: add compatible for es8323-i2c
+
+Add a compatible for the everest,es8323 audio codec used with a number
+of Amlogic and Rockchip board devices.
+
+Signed-off-by: Romain Perier <romain.perier@collabora.com>
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+Acked-by: Rob Herring <robh@kernel.org>
+---
+ Documentation/devicetree/bindings/sound/es8328.txt | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/Documentation/devicetree/bindings/sound/es8328.txt b/Documentation/devicetree/bindings/sound/es8328.txt
+index 33fbf058c997..86b6d6e99732 100644
+--- a/Documentation/devicetree/bindings/sound/es8328.txt
++++ b/Documentation/devicetree/bindings/sound/es8328.txt
+@@ -4,7 +4,10 @@ This device supports both I2C and SPI.
+
+ Required properties:
+
+- - compatible : Should be "everest,es8328" or "everest,es8388"
++ - compatible : Should be one of the following:
++ - "everest,es8323"
++ - "everest,es8328"
++ - "everest,es8388"
+ - DVDD-supply : Regulator providing digital core supply voltage 1.8 - 3.6V
+ - AVDD-supply : Regulator providing analog supply voltage 3.3V
+ - PVDD-supply : Regulator providing digital IO supply voltage 1.8 - 3.6V
+--
+2.17.1
+
new file mode 100644
@@ -0,0 +1,37 @@
+From 7c7014c03b5bbbec7231836f836a26b0237f31cf Mon Sep 17 00:00:00 2001
+From: Romain Perier <romain.perier@collabora.com>
+Date: Sun, 14 Aug 2022 04:29:32 +0000
+Subject: [PATCH 73/73] WIP: ASoC: codecs: add support for ES8323
+
+The ES8323 is compatible with the existing ES8328 codec driver, so add
+compatibles allowing it to be used.
+
+Signed-off-by: Romain Perier <romain.perier@collabora.com>
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+---
+ sound/soc/codecs/es8328-i2c.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/sound/soc/codecs/es8328-i2c.c b/sound/soc/codecs/es8328-i2c.c
+index 68072e99fcc7..57c7de5cfa05 100644
+--- a/sound/soc/codecs/es8328-i2c.c
++++ b/sound/soc/codecs/es8328-i2c.c
+@@ -16,6 +16,7 @@
+ #include "es8328.h"
+
+ static const struct i2c_device_id es8328_id[] = {
++ { "es8323", 0 },
+ { "es8328", 0 },
+ { "es8388", 0 },
+ { }
+@@ -23,6 +24,7 @@ static const struct i2c_device_id es8328_id[] = {
+ MODULE_DEVICE_TABLE(i2c, es8328_id);
+
+ static const struct of_device_id es8328_of_match[] = {
++ { .compatible = "everest,es8323", },
+ { .compatible = "everest,es8328", },
+ { .compatible = "everest,es8388", },
+ { }
+--
+2.17.1
+
--
2.38.1