From a6a44f94bf8ccae8c7843ac3db2d606b961976c2 Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Mon, 21 Oct 2024 17:14:41 -0700 Subject: [PATCH 01/27] ramips: linkit: replace driver with gpio-hog It does the same thing minus a few dmesg prints. Signed-off-by: Rosen Penev Link: https://github.com/openwrt/openwrt/pull/16788 Signed-off-by: Robert Marko --- .../mt7628an_mediatek_linkit-smart-7688.dts | 15 +-- .../patches-6.6/855-linkit_bootstrap.patch | 97 ------------------- 2 files changed, 9 insertions(+), 103 deletions(-) delete mode 100644 target/linux/ramips/patches-6.6/855-linkit_bootstrap.patch diff --git a/target/linux/ramips/dts/mt7628an_mediatek_linkit-smart-7688.dts b/target/linux/ramips/dts/mt7628an_mediatek_linkit-smart-7688.dts index fdce5cbec5e..34ef15eca0b 100644 --- a/target/linux/ramips/dts/mt7628an_mediatek_linkit-smart-7688.dts +++ b/target/linux/ramips/dts/mt7628an_mediatek_linkit-smart-7688.dts @@ -22,12 +22,6 @@ serial0 = &uart2; }; - bootstrap { - compatible = "mediatek,linkit"; - - status = "okay"; - }; - leds { compatible = "gpio-leds"; @@ -144,6 +138,15 @@ }; }; +&gpio { + bootstrap { + gpio-hog; + line-name = "bootstrap"; + output-low; + gpios = <11 GPIO_ACTIVE_LOW>; + }; +}; + &i2c { status = "okay"; }; diff --git a/target/linux/ramips/patches-6.6/855-linkit_bootstrap.patch b/target/linux/ramips/patches-6.6/855-linkit_bootstrap.patch deleted file mode 100644 index 16eaf619a03..00000000000 --- a/target/linux/ramips/patches-6.6/855-linkit_bootstrap.patch +++ /dev/null @@ -1,97 +0,0 @@ ---- a/drivers/misc/Makefile -+++ b/drivers/misc/Makefile -@@ -52,6 +52,7 @@ obj-$(CONFIG_ECHO) += echo/ - obj-$(CONFIG_CXL_BASE) += cxl/ - obj-$(CONFIG_DW_XDATA_PCIE) += dw-xdata-pcie.o - obj-$(CONFIG_PCI_ENDPOINT_TEST) += pci_endpoint_test.o -+obj-$(CONFIG_SOC_MT7620) += linkit.o - obj-$(CONFIG_OCXL) += ocxl/ - obj-$(CONFIG_BCM_VK) += bcm-vk/ - obj-y += cardreader/ ---- /dev/null -+++ b/drivers/misc/linkit.c -@@ -0,0 +1,84 @@ -+/* -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * publishhed by the Free Software Foundation. -+ * -+ * Copyright (C) 2015 John Crispin -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#define LINKIT_LATCH_GPIO 11 -+ -+struct linkit_hw_data { -+ char board[16]; -+ char rev[16]; -+}; -+ -+static void sanify_string(char *s) -+{ -+ int i; -+ -+ for (i = 0; i < 15; i++) -+ if (s[i] <= 0x20) -+ s[i] = '\0'; -+ s[15] = '\0'; -+} -+ -+static int linkit_probe(struct platform_device *pdev) -+{ -+ struct linkit_hw_data hw; -+ struct mtd_info *mtd; -+ size_t retlen; -+ int ret; -+ -+ mtd = get_mtd_device_nm("factory"); -+ if (IS_ERR(mtd)) -+ return PTR_ERR(mtd); -+ -+ ret = mtd_read(mtd, 0x400, sizeof(hw), &retlen, (u_char *) &hw); -+ put_mtd_device(mtd); -+ -+ sanify_string(hw.board); -+ sanify_string(hw.rev); -+ -+ dev_info(&pdev->dev, "Version : %s\n", hw.board); -+ dev_info(&pdev->dev, "Revision : %s\n", hw.rev); -+ -+ if (!strcmp(hw.board, "LINKITS7688")) { -+ dev_info(&pdev->dev, "setting up bootstrap latch\n"); -+ -+ if (devm_gpio_request(&pdev->dev, LINKIT_LATCH_GPIO, "bootstrap")) { -+ dev_err(&pdev->dev, "failed to setup bootstrap gpio\n"); -+ return -1; -+ } -+ gpio_direction_output(LINKIT_LATCH_GPIO, 0); -+ } -+ -+ return 0; -+} -+ -+static const struct of_device_id linkit_match[] = { -+ { .compatible = "mediatek,linkit" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, linkit_match); -+ -+static struct platform_driver linkit_driver = { -+ .probe = linkit_probe, -+ .driver = { -+ .name = "mtk-linkit", -+ .owner = THIS_MODULE, -+ .of_match_table = linkit_match, -+ }, -+}; -+ -+int __init linkit_init(void) -+{ -+ return platform_driver_register(&linkit_driver); -+} -+late_initcall_sync(linkit_init); From ade045084bd3f86969eaf0b35234aaa01e430fe1 Mon Sep 17 00:00:00 2001 From: John Thomson Date: Wed, 16 Oct 2024 07:13:25 +1000 Subject: [PATCH 02/27] kernel: mtdsplit_minor: return 0 if not fatal Introduced with Linux 6.7, in commit: 5c2f7727d437 ("mtd: mtdpart: check for subpartitions parsing result"), when a parser returns an error, this will be passed up, and consequently, all parent mtd partitions get torn down. Adjust the MiNOR mtdsplit driver to only return an error if there is a critical problem in reading from the mtd device or allocating memory. Otherwise return 0 to indicate that no partitions were found. Also add logging to indicate what went wrong. This mtdsplit parser makes a very limited check of the first YAFFS header. For example, this will not match expectations when initially booting an initramfs image with OEM on MTD. Signed-off-by: John Thomson Acked-by: Thibaut VARENE Link: https://github.com/openwrt/openwrt/pull/16780 Signed-off-by: Robert Marko --- .../drivers/mtd/mtdsplit/mtdsplit_minor.c | 44 ++++++++++++------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_minor.c b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_minor.c index af6822e11ab..be69de57987 100644 --- a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_minor.c +++ b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_minor.c @@ -61,29 +61,43 @@ static int mtdsplit_parse_minor(struct mtd_info *master, hdr_len = sizeof(hdr); err = mtd_read(master, 0, hdr_len, &retlen, (void *) &hdr); - if (err) + if (err) { + pr_err("MiNOR mtd_read error: %d\n", err); return err; + } - if (retlen != hdr_len) + if (retlen != hdr_len) { + pr_err("MiNOR mtd_read too short\n"); return -EIO; + } /* match header */ - if (hdr.yaffs_type != YAFFS_OBJECT_TYPE_FILE) - return -EINVAL; - - if (hdr.yaffs_obj_id != YAFFS_OBJECTID_ROOT) - return -EINVAL; - - if (hdr.yaffs_sum_unused != YAFFS_SUM_UNUSED) - return -EINVAL; - - if (memcmp(hdr.yaffs_name, YAFFS_NAME, sizeof(YAFFS_NAME))) - return -EINVAL; + if (hdr.yaffs_type != YAFFS_OBJECT_TYPE_FILE) { + pr_info("MiNOR YAFFS first type not matched\n"); + return 0; + } + + if (hdr.yaffs_obj_id != YAFFS_OBJECTID_ROOT) { + pr_info("MiNOR YAFFS first objectid not matched\n"); + return 0; + } + + if (hdr.yaffs_sum_unused != YAFFS_SUM_UNUSED) { + pr_info("MiNOR YAFFS first sum not matched\n"); + return 0; + } + + if (memcmp(hdr.yaffs_name, YAFFS_NAME, sizeof(YAFFS_NAME))) { + pr_info("MiNOR YAFFS first name not matched\n"); + return 0; + } err = mtd_find_rootfs_from(master, master->erasesize, master->size, &rootfs_offset, NULL); - if (err) - return err; + if (err) { + pr_info("MiNOR mtd_find_rootfs_from error: %d\n", err); + return 0; + } parts = kzalloc(MINOR_NR_PARTS * sizeof(*parts), GFP_KERNEL); if (!parts) From 36834ea3403d05b6beab3a2efc3f00f097e58c81 Mon Sep 17 00:00:00 2001 From: John Thomson Date: Wed, 16 Oct 2024 12:51:22 +1000 Subject: [PATCH 03/27] kernel: mtdsplit_minor: accept bootimage filename RouterBOOT v7 on NOR devices no longer accepts the YAFFS kernel ELF method of booting. It will accept an NPK image named bootimage. Adjust mtdsplit_minor to accept this second possible boot file name. Use the conservative value of 127 for YAFFS max name length (used when YAFFS compiled with unicode support) vs 255. Signed-off-by: John Thomson Acked-by: Thibaut VARENE Link: https://github.com/openwrt/openwrt/pull/16780 Signed-off-by: Robert Marko --- .../generic/files/drivers/mtd/mtdsplit/mtdsplit_minor.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_minor.c b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_minor.c index be69de57987..053cba6272d 100644 --- a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_minor.c +++ b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_minor.c @@ -34,7 +34,9 @@ #define YAFFS_OBJECT_TYPE_FILE 0x1 #define YAFFS_OBJECTID_ROOT 0x1 #define YAFFS_SUM_UNUSED 0xFFFF -#define YAFFS_NAME "kernel" +#define YAFFS_MAX_NAME_LENGTH 127 +#define YAFFS_NAME_KERNEL "kernel" +#define YAFFS_NAME_BOOTIMAGE "bootimage" #define MINOR_NR_PARTS 2 @@ -46,7 +48,7 @@ struct minor_header { int yaffs_type; int yaffs_obj_id; u16 yaffs_sum_unused; - char yaffs_name[sizeof(YAFFS_NAME)]; + char yaffs_name[YAFFS_MAX_NAME_LENGTH]; }; static int mtdsplit_parse_minor(struct mtd_info *master, @@ -87,7 +89,8 @@ static int mtdsplit_parse_minor(struct mtd_info *master, return 0; } - if (memcmp(hdr.yaffs_name, YAFFS_NAME, sizeof(YAFFS_NAME))) { + if ((memcmp(hdr.yaffs_name, YAFFS_NAME_KERNEL, sizeof(YAFFS_NAME_KERNEL))) && + (memcmp(hdr.yaffs_name, YAFFS_NAME_BOOTIMAGE, sizeof(YAFFS_NAME_BOOTIMAGE)))) { pr_info("MiNOR YAFFS first name not matched\n"); return 0; } From 07b845b1f2e7417c39f3585d971b05f7ab3ce08b Mon Sep 17 00:00:00 2001 From: Paul Spooren Date: Tue, 29 Oct 2024 11:09:24 +0100 Subject: [PATCH 04/27] build: don't include kernel/libc in package index The same that is done in `ipkg-make-index.sh` should happen with APK. If the pseudo packages, only added to add dependency constraints, are added to the index, APK happily "upgrades" them and installs updated kmods, too. However, the Kernel itself is never installed via a regular package. Fixes: https://github.com/openwrt/openwrt/issues/16808 Signed-off-by: Paul Spooren --- package/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/Makefile b/package/Makefile index 9ae94e9a4eb..abe76a619fa 100644 --- a/package/Makefile +++ b/package/Makefile @@ -130,7 +130,7 @@ ifneq ($(CONFIG_USE_APK),) --keys-dir $(TOPDIR) \ --sign $(BUILD_KEY_APK_SEC) \ --output packages.adb \ - *.apk; \ + $$(ls *.apk | grep -v 'kernel\|libc'); \ done else @for d in $(PACKAGE_SUBDIRS); do ( \ From 559df6cb99c38be124ebe1b2211aaf368451a8b3 Mon Sep 17 00:00:00 2001 From: Paul Spooren Date: Wed, 30 Oct 2024 09:28:30 +0100 Subject: [PATCH 05/27] build: Honor DEFAULT_VARIANT for APK packages Previously APK would complain as it wasn't sure which package to install by default when multiple packages would provide the same name. Now, give the package a higher provider priority to make APK automatically select the "default" package. Signed-off-by: Paul Spooren --- include/package-pack.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/include/package-pack.mk b/include/package-pack.mk index a677318ca24..9d06c8b6471 100644 --- a/include/package-pack.mk +++ b/include/package-pack.mk @@ -355,6 +355,7 @@ else ) \ ), \ $$(prov) )" \ + $(if $(DEFAULT_VARIANT),--info "provider-priority:100") \ --script "post-install:$$(ADIR_$(1))/post-install" \ --script "pre-deinstall:$$(ADIR_$(1))/pre-deinstall" \ --info "depends:$$(foreach depends,$$(subst $$(comma),$$(space),$$(subst $$(space),,$$(subst $$(paren_right),,$$(subst $$(paren_left),,$$(Package/$(1)/DEPENDS))))),$$(depends))" \ From d6c6e4f722be253cf3e46c2fd1629f5312a6514f Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Wed, 30 Oct 2024 10:23:10 +0100 Subject: [PATCH 06/27] mvebu: cortexa9: drop removal of firewall4 package Drop removal of firewall4 package for Synology DS213j device. With OPKG the firewall4 package was installed anyway as it's a dependency of luci-app-firewall and was silently installed again later in such condition. Drop it to fix support for APK. Signed-off-by: Christian Marangi --- target/linux/mvebu/image/cortexa9.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/linux/mvebu/image/cortexa9.mk b/target/linux/mvebu/image/cortexa9.mk index a396b486751..6e49045f684 100644 --- a/target/linux/mvebu/image/cortexa9.mk +++ b/target/linux/mvebu/image/cortexa9.mk @@ -444,6 +444,6 @@ define Device/synology_ds213j DEVICE_PACKAGES := \ kmod-rtc-s35390a kmod-hwmon-gpiofan kmod-hwmon-drivetemp \ kmod-md-raid0 kmod-md-raid1 kmod-md-mod e2fsprogs mdadm \ - -ppp -kmod-nft-offload -firewall4 -dnsmasq -odhcpd-ipv6only + -ppp -kmod-nft-offload -dnsmasq -odhcpd-ipv6only endef TARGET_DEVICES += synology_ds213j From f9afff8b280d98103de5da12de46ef9580e130d3 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Wed, 30 Oct 2024 10:25:25 +0100 Subject: [PATCH 07/27] mxs: drop removal of firewall4 package Drop removal of firewall4 package for I2SE Duckbill device. With OPKG the firewall4 package was installed anyway as it's a dependency of luci-app-firewall and was silently installed again later in such condition. Drop it to fix support for APK. Signed-off-by: Christian Marangi --- target/linux/mxs/image/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/linux/mxs/image/Makefile b/target/linux/mxs/image/Makefile index e5ba0a221ae..b95409741ab 100644 --- a/target/linux/mxs/image/Makefile +++ b/target/linux/mxs/image/Makefile @@ -46,7 +46,7 @@ endef define Device/i2se_duckbill DEVICE_VENDOR := I2SE DEVICE_MODEL := Duckbill - DEVICE_PACKAGES := -dnsmasq -firewall4 -ppp -ip6tables -iptables -mtd \ + DEVICE_PACKAGES := -dnsmasq -ppp -ip6tables -iptables -mtd \ uboot-envtools kmod-leds-gpio -kmod-nf-nathelper SUPPORTED_DEVICES:=i2se,duckbill SOC:=imx28 From 618f079f5d03edfd82fe7949f16c61acef9408a2 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Wed, 30 Oct 2024 11:19:33 +0100 Subject: [PATCH 08/27] build: correctly ignore Initramfs image on error Correctly ignore Initramfs image copy on error. This follows the pattern with sysupgrade image where an image might fail as it's too big or the generation command fails and there is nothing to copy to the bin directory. Signed-off-by: Christian Marangi --- include/image.mk | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/image.mk b/include/image.mk index c476f6674f5..a4ac1b49cf8 100644 --- a/include/image.mk +++ b/include/image.mk @@ -542,6 +542,9 @@ define Device/Build/initramfs $(call Kernel/CompileImage/Initramfs,$(KDIR)/target-dir-$$(ROOTFS_ID/$(1)),.$$(ROOTFS_ID/$(1))) endif $(1)-initramfs-images: $$(if $$(KERNEL_INITRAMFS),$(BIN_DIR)/$$(KERNEL_INITRAMFS_IMAGE)) + + .IGNORE: $(BIN_DIR)/$$(KERNEL_INITRAMFS_IMAGE) + $(BIN_DIR)/$$(KERNEL_INITRAMFS_IMAGE): $(KDIR)/tmp/$$(KERNEL_INITRAMFS_IMAGE) cp $$^ $$@ From 5ba701fe1916c32dd00a1f9dbd93ae362740ab52 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Wed, 30 Oct 2024 11:21:58 +0100 Subject: [PATCH 09/27] image: ignore errors from mktplinkfw command Rework tplink-v2-header and tplink-v2-image Build define to ignore error if mktplinkfw2 errors out. This is to handle situation when the image is too big and can't be generated or prev check-image calls deleted the source file as it's too big. This aligns to the pattern used by tplink-v1-image. Signed-off-by: Christian Marangi --- include/image-commands.mk | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/include/image-commands.mk b/include/image-commands.mk index d2974f4e015..702cbd8c989 100644 --- a/include/image-commands.mk +++ b/include/image-commands.mk @@ -666,23 +666,22 @@ define Build/tplink-v1-image endef define Build/tplink-v2-header - $(STAGING_DIR_HOST)/bin/mktplinkfw2 \ + -$(STAGING_DIR_HOST)/bin/mktplinkfw2 \ -c -H $(TPLINK_HWID) -W $(TPLINK_HWREV) -L $(KERNEL_LOADADDR) \ -E $(if $(KERNEL_ENTRY),$(KERNEL_ENTRY),$(KERNEL_LOADADDR)) \ -w $(TPLINK_HWREVADD) -F "$(TPLINK_FLASHLAYOUT)" \ -T $(TPLINK_HVERSION) -V "ver. 2.0" \ - -k $@ -o $@.new $(1) - @mv $@.new $@ + -k $@ -o $@.new $(1) \ + && mv $@.new $@ || rm -f $@ endef define Build/tplink-v2-image - $(STAGING_DIR_HOST)/bin/mktplinkfw2 \ + -$(STAGING_DIR_HOST)/bin/mktplinkfw2 \ -H $(TPLINK_HWID) -W $(TPLINK_HWREV) \ -w $(TPLINK_HWREVADD) -F "$(TPLINK_FLASHLAYOUT)" \ -T $(TPLINK_HVERSION) -V "ver. 2.0" -a 0x4 -j \ - -k $(IMAGE_KERNEL) -r $(IMAGE_ROOTFS) -o $@.new $(1) - cat $@.new >> $@ - rm -rf $@.new + -k $(IMAGE_KERNEL) -r $(IMAGE_ROOTFS) -o $@.new $(1) \ + && cat $@.new >> $@ && rm -rf $@.new || rm -f $@ endef define Build/uImage From f303471ae9048ddeb068a64df7aeaab782fb1cb0 Mon Sep 17 00:00:00 2001 From: Paul Spooren Date: Wed, 30 Oct 2024 13:41:23 +0100 Subject: [PATCH 10/27] imagebuilder: fix copying of missing kernel/libc Those packages were not copied due to OPKG using an underscore while APK uses dashes. Remove that char to copy kernel/libc for either APK/OPKG. Signed-off-by: Paul Spooren --- target/imagebuilder/Makefile | 4 ++-- target/imagebuilder/files/Makefile | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/target/imagebuilder/Makefile b/target/imagebuilder/Makefile index 1e58fad8e9a..bdbbb45cb1f 100644 --- a/target/imagebuilder/Makefile +++ b/target/imagebuilder/Makefile @@ -71,7 +71,7 @@ endif ifeq ($(CONFIG_BUILDBOT),) ifeq ($(CONFIG_IB_STANDALONE),) $(FIND) $(call FeedPackageDir,libc) -type f \ - \( -name 'libc_*.$(PACKAGE_SUFFIX)' -or -name 'kernel_*.$(PACKAGE_SUFFIX)' -or -name 'kmod-*.$(PACKAGE_SUFFIX)' \) \ + \( -name 'libc*.$(PACKAGE_SUFFIX)' -or -name 'kernel*.$(PACKAGE_SUFFIX)' -or -name 'kmod-*.$(PACKAGE_SUFFIX)' \) \ -exec $(CP) -t $(PKG_BUILD_DIR)/packages {} + else $(FIND) $(wildcard $(PACKAGE_SUBDIRS)) -type f -name '*.$(PACKAGE_SUFFIX)' \ @@ -79,7 +79,7 @@ ifeq ($(CONFIG_BUILDBOT),) endif else $(FIND) $(call FeedPackageDir,libc) -type f \ - \( -name 'libc_*.$(PACKAGE_SUFFIX)' -or -name 'kernel_*.$(PACKAGE_SUFFIX)' \) \ + \( -name 'libc*.$(PACKAGE_SUFFIX)' -or -name 'kernel*.$(PACKAGE_SUFFIX)' \) \ -exec $(CP) -t $(IB_LDIR)/ {} + endif diff --git a/target/imagebuilder/files/Makefile b/target/imagebuilder/files/Makefile index 24de26c7712..f46b61b7870 100644 --- a/target/imagebuilder/files/Makefile +++ b/target/imagebuilder/files/Makefile @@ -228,8 +228,8 @@ ifeq ($(CONFIG_USE_APK),) $(OPKG) install $(firstword $(wildcard $(LINUX_DIR)/kernel_*.ipk $(PACKAGE_DIR)/kernel_*.ipk)) $(OPKG) install $(BUILD_PACKAGES) else - $(APK) add --no-scripts $(firstword $(wildcard $(LINUX_DIR)/libc-*.apk $(PACKAGE_DIR)/libc_*.apk)) - $(APK) add --no-scripts $(firstword $(wildcard $(LINUX_DIR)/kernel-*.apk $(PACKAGE_DIR)/kernel_*.apk)) + $(APK) add --no-scripts $(firstword $(wildcard $(LINUX_DIR)/libc-*.apk $(PACKAGE_DIR)/libc-*.apk)) + $(APK) add --no-scripts $(firstword $(wildcard $(LINUX_DIR)/kernel-*.apk $(PACKAGE_DIR)/kernel-*.apk)) $(APK) add --no-scripts $(BUILD_PACKAGES) endif From def70fa85b242465ee14c69dc6f57cd42f860a5e Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Wed, 30 Oct 2024 14:05:10 +0100 Subject: [PATCH 11/27] image: ignore errors from more commands Ignore errors in more image commands to handle case where the image is too big and check-image validation fails. Signed-off-by: Christian Marangi --- include/image-commands.mk | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/include/image-commands.mk b/include/image-commands.mk index 702cbd8c989..2568fb3ade5 100644 --- a/include/image-commands.mk +++ b/include/image-commands.mk @@ -316,12 +316,12 @@ define Build/elecom-product-header $(eval product=$(word 1,$(1))) $(eval fw=$(if $(word 2,$(1)),$(word 2,$(1)),$@)) - ( \ + -( \ echo -n -e "ELECOM\x00\x00$(product)" | dd bs=40 count=1 conv=sync; \ echo -n "0.00" | dd bs=16 count=1 conv=sync; \ dd if=$(fw); \ - ) > $(fw).new - mv $(fw).new $(fw) + ) > $(fw).new \ + && mv $(fw).new $(fw) || rm -f $(fw) endef define Build/elecom-wrc-gs-factory @@ -351,10 +351,10 @@ define Build/elx-header echo -ne "$$($(MKHASH) md5 $@ | fold -s2 | xargs -I {} echo \\x{} | tr -d '\n')" | \ dd bs=58 count=1 conv=sync; \ ) > $(KDIR)/tmp/$(DEVICE_NAME).header - $(call Build/xor-image,-p $(xor_pattern) -x) - cat $(KDIR)/tmp/$(DEVICE_NAME).header $@ > $@.new - mv $@.new $@ - rm -rf $(KDIR)/tmp/$(DEVICE_NAME).header + -$(call Build/xor-image,-p $(xor_pattern) -x) \ + && cat $(KDIR)/tmp/$(DEVICE_NAME).header $@ > $@.new \ + && mv $@.new $@ \ + && rm -rf $(KDIR)/tmp/$(DEVICE_NAME).header endef define Build/eva-image @@ -614,8 +614,8 @@ define Build/seama-seal endef define Build/senao-header - $(STAGING_DIR_HOST)/bin/mksenaofw $(1) -e $@ -o $@.new - mv $@.new $@ + -$(STAGING_DIR_HOST)/bin/mksenaofw $(1) -e $@ -o $@.new \ + && mv $@.new $@ || rm -f $@ endef define Build/sysupgrade-tar @@ -718,8 +718,8 @@ define Build/multiImage endef define Build/xor-image - $(STAGING_DIR_HOST)/bin/xorimage -i $@ -o $@.xor $(1) - mv $@.xor $@ + -$(STAGING_DIR_HOST)/bin/xorimage -i $@ -o $@.xor $(1) \ + && mv $@.xor $@ || rm -f $@ endef define Build/zip From 73edd3a41e3fb0bbb0c255554fd5c0b99d701e24 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Wed, 30 Oct 2024 14:07:22 +0100 Subject: [PATCH 12/27] ramips: ignore errors from trx utility Ignore errors from trx utility to handle case with image too big. Signed-off-by: Christian Marangi --- target/linux/ramips/image/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/linux/ramips/image/Makefile b/target/linux/ramips/image/Makefile index fdc15aa1efc..56971769434 100644 --- a/target/linux/ramips/image/Makefile +++ b/target/linux/ramips/image/Makefile @@ -140,7 +140,7 @@ define Build/sign-dlink-ru endef define Build/trx - $(STAGING_DIR_HOST)/bin/trx $(1) \ + -$(STAGING_DIR_HOST)/bin/trx $(1) \ -o $@ \ -m $$(($(call exp_units,$(IMAGE_SIZE)))) \ -f $(IMAGE_KERNEL) \ From b5e1544f4d45795ab8750b1054c54c8880b7b96b Mon Sep 17 00:00:00 2001 From: Rafal Boni Date: Thu, 24 Oct 2024 03:06:22 -0400 Subject: [PATCH 13/27] ipq806x: Revert "ipq806x: swap lan leds for Meraki MR52" This reverts commit ec8f647d168fa8f3b1eedd9b5fe665f793f3a659, as with the current kernel version, the change actually causes the same bug it once may have fixed -- that is, the leds are now again reversed. I suspect this was due to a switch to a newer kernel version between when the patch was submitted and now reversing the order of the interfaces, so that eth0 / the LAN interface is also the interface used for PoE, and eth1 / the WAN interface is the non-PoE interface. Signed-off-by: Rafal Boni Link: https://github.com/openwrt/openwrt/pull/16779 Signed-off-by: Robert Marko --- .../arch/arm/boot/dts/qcom/qcom-ipq8068-mr52.dts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/target/linux/ipq806x/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq8068-mr52.dts b/target/linux/ipq806x/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq8068-mr52.dts index 0d3230e6de9..97b280e2015 100644 --- a/target/linux/ipq806x/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq8068-mr52.dts +++ b/target/linux/ipq806x/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq8068-mr52.dts @@ -48,12 +48,12 @@ lan1_green { label = "green:lan1"; - gpios = <&qcom_pinmux 23 GPIO_ACTIVE_HIGH>; + gpios = <&qcom_pinmux 24 GPIO_ACTIVE_HIGH>; }; lan2_green { label = "green:lan2"; - gpios = <&qcom_pinmux 24 GPIO_ACTIVE_HIGH>; + gpios = <&qcom_pinmux 23 GPIO_ACTIVE_HIGH>; }; led_active: active { @@ -63,12 +63,12 @@ lan1_orange { label = "orange:lan1"; - gpios = <&qcom_pinmux 60 GPIO_ACTIVE_HIGH>; + gpios = <&qcom_pinmux 62 GPIO_ACTIVE_HIGH>; }; lan2_orange { label = "orange:lan2"; - gpios = <&qcom_pinmux 62 GPIO_ACTIVE_HIGH>; + gpios = <&qcom_pinmux 60 GPIO_ACTIVE_HIGH>; }; }; }; From cdc607d535b8ccd0f7072eaf8f9990cb98cd03cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Wed, 30 Oct 2024 13:49:02 +0100 Subject: [PATCH 14/27] bcm27xx-utils: update to latest version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes build with GCC 14. Full changelog: https://github.com/raspberrypi/utils/compare/451b9881b72cb994c102724b5a7d9b93f97dc315...6a2a6becebbc38fde34a94386457ac8210f9119b Signed-off-by: Álvaro Fernández Rojas --- package/utils/bcm27xx-utils/Makefile | 8 +++++--- .../patches/0001-raspinfo-adapt-to-OpenWrt.patch | 9 +++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/package/utils/bcm27xx-utils/Makefile b/package/utils/bcm27xx-utils/Makefile index 17618b7ef7a..8f5d91da8f1 100644 --- a/package/utils/bcm27xx-utils/Makefile +++ b/package/utils/bcm27xx-utils/Makefile @@ -3,13 +3,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=bcm27xx-utils -PKG_VERSION:=2024.04.24 +PKG_VERSION:=2024.10.25 PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://github.com/raspberrypi/utils.git -PKG_SOURCE_VERSION:=451b9881b72cb994c102724b5a7d9b93f97dc315 -PKG_MIRROR_HASH:=595ad8eadd9756132dee4b7d1b2466cb9fb8efa2015e6fbd4ab983e1a00afcf4 +PKG_SOURCE_VERSION:=6a2a6becebbc38fde34a94386457ac8210f9119b +PKG_MIRROR_HASH:=a775c7ffb9fac2d798ec8e0a4c7707eb7133cbc9c4418a1cf9434f87c42c01bb PKG_FLAGS:=nonshared PKG_BUILD_FLAGS:=no-lto @@ -46,6 +46,8 @@ define Package/bcm27xx-utils/install $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/eepflash.sh $(1)/usr/bin $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/eepmake $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/kdtc $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/otpset $(1)/usr/bin $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/overlaycheck $(1)/usr/bin diff --git a/package/utils/bcm27xx-utils/patches/0001-raspinfo-adapt-to-OpenWrt.patch b/package/utils/bcm27xx-utils/patches/0001-raspinfo-adapt-to-OpenWrt.patch index 9dd6d99626e..26f8f6e4e3c 100644 --- a/package/utils/bcm27xx-utils/patches/0001-raspinfo-adapt-to-OpenWrt.patch +++ b/package/utils/bcm27xx-utils/patches/0001-raspinfo-adapt-to-OpenWrt.patch @@ -242,6 +242,15 @@ Signed-off-by: Álvaro Fernández Rojas else echo "vcdbg not found" fi +@@ -275,7 +111,7 @@ echo "dmesg log" + echo "---------" + echo + +-sudo dmesg | sed -e "s/\([0-9a-fA-F]\{1,4\}:\)\{7,7\}[0-9a-fA-F]\{1,4\}/y.y.y.y.y.y.y.y/g" | sed -e "s/[0-9a-fA-F]\{1,4\}:\(:[0-9a-fA-F]\{1,4\}\)\{1,4\}/y::y.y.y.y/g" | sed -e "s/\([0-9a-fA-F]\{2,2\}\:\)\{5,5\}[0-9a-fA-F]\{2,2\}/m.m.m.m/g" ++dmesg | sed -e "s/\([0-9a-fA-F]\{1,4\}:\)\{7,7\}[0-9a-fA-F]\{1,4\}/y.y.y.y.y.y.y.y/g" | sed -e "s/[0-9a-fA-F]\{1,4\}:\(:[0-9a-fA-F]\{1,4\}\)\{1,4\}/y::y.y.y.y/g" | sed -e "s/\([0-9a-fA-F]\{2,2\}\:\)\{5,5\}[0-9a-fA-F]\{2,2\}/m.m.m.m/g" + + + if grep -q "^Revision\s*:\s*[ 123][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]1[13457][0-9a-fA-F]$" /proc/cpuinfo @@ -284,5 +120,9 @@ echo echo "EEPROM" echo "------" From 67b0cd8976bb95092f5dcebc9cba93eb8e14798e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Thu, 31 Oct 2024 08:52:16 +0100 Subject: [PATCH 15/27] CI: labeler: add bcm27xx-utils MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bcm27xx-utils can only be built for bcm27xx target. Signed-off-by: Álvaro Fernández Rojas --- .github/labeler.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/labeler.yml b/.github/labeler.yml index 99a7c665df9..ede4bb5a02f 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -30,6 +30,7 @@ - any-glob-to-any-file: - "target/linux/bcm27xx/**" - "package/kernel/bcm27xx-gpu-fw/**" + - "package/utils/bcm27xx-utils/**" "target/bcm47xx": - changed-files: - any-glob-to-any-file: From 9c6cd2241dd083f9e25d256bfd292a880b88d8b7 Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Fri, 25 Oct 2024 15:39:30 -0700 Subject: [PATCH 16/27] ramips: m4r v4: fix typo It should be debounce-interval, as with the others. Signed-off-by: Rosen Penev Link: https://github.com/openwrt/openwrt/pull/16802 Signed-off-by: Robert Marko --- target/linux/ramips/dts/mt7621_tplink_deco-m4r-v4.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/linux/ramips/dts/mt7621_tplink_deco-m4r-v4.dts b/target/linux/ramips/dts/mt7621_tplink_deco-m4r-v4.dts index 9f30f935509..6274f985998 100644 --- a/target/linux/ramips/dts/mt7621_tplink_deco-m4r-v4.dts +++ b/target/linux/ramips/dts/mt7621_tplink_deco-m4r-v4.dts @@ -35,7 +35,7 @@ led { label = "led"; gpios = <&gpio 2 GPIO_ACTIVE_LOW>; - debounce_interval = <60>; + debounce-interval = <60>; linux,code = ; }; From 7afdbc0955a58f39ffd0ea507e867774954acfb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Thu, 31 Oct 2024 00:25:41 +0100 Subject: [PATCH 17/27] bcm27xx-gpu-fw: update to latest version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use release tar instead of downloading separate files. Full changelog: https://github.com/raspberrypi/firmware/compare/1.20240424...1.20241008 Signed-off-by: Álvaro Fernández Rojas --- package/kernel/bcm27xx-gpu-fw/Makefile | 177 +++---------------------- 1 file changed, 22 insertions(+), 155 deletions(-) diff --git a/package/kernel/bcm27xx-gpu-fw/Makefile b/package/kernel/bcm27xx-gpu-fw/Makefile index c6d53de7c78..6de2fd7501c 100644 --- a/package/kernel/bcm27xx-gpu-fw/Makefile +++ b/package/kernel/bcm27xx-gpu-fw/Makefile @@ -2,130 +2,20 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=bcm27xx-gpu-fw -PKG_RELEASE_HASH:=969420b4121b522ab33c5001074cc4c2547dafaf -PKG_VERSION:=2024.04.24~$(PKG_RELEASE_HASH) +PKG_VERSION:=2024.10.08 +PKG_VERSION_REAL:=1.$(subst .,,$(PKG_VERSION)) PKG_RELEASE:=1 -PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)/rpi-firmware-$(PKG_RELEASE_HASH) +PKG_SOURCE:=raspi-firmware_$(PKG_VERSION_REAL).orig.tar.xz +PKG_SOURCE_URL:=https://github.com/raspberrypi/firmware/releases/download/$(PKG_VERSION_REAL) +PKG_HASH:=11e7bedcd0f52729bbc82ae8de3cb3f52eb4ae3d6bdb3e11fbfdbea9c4a2b1c3 PKG_FLAGS:=nonshared include $(INCLUDE_DIR)/package.mk -RPI_FIRMWARE_URL:=@GITHUB/raspberrypi/firmware/$(PKG_RELEASE_HASH)/boot/ -RPI_FIRMWARE_FILE:=rpi-firmware-$(PKG_RELEASE_HASH) - -define Download/LICENCE_broadcom - FILE:=$(RPI_FIRMWARE_FILE)-LICENCE.broadcom - URL:=$(RPI_FIRMWARE_URL) - URL_FILE:=LICENCE.broadcom - HASH:=c7283ff51f863d93a275c66e3b4cb08021a5dd4d8c1e7acc47d872fbe52d3d6b -endef -$(eval $(call Download,LICENCE_broadcom)) - -define Download/bootcode_bin - FILE:=$(RPI_FIRMWARE_FILE)-bootcode.bin - URL:=$(RPI_FIRMWARE_URL) - URL_FILE:=bootcode.bin - HASH:=af603ebd97e7b692c30195563f7b25656eb05d57838cf1a715ebb470d1614ce4 -endef -$(eval $(call Download,bootcode_bin)) - -define Download/fixup_dat - FILE:=$(RPI_FIRMWARE_FILE)-fixup.dat - URL:=$(RPI_FIRMWARE_URL) - URL_FILE:=fixup.dat - HASH:=94ae3ff8363a6a2832f173241597b6500cf67044d34155a1251fe58671dd6ce7 -endef -$(eval $(call Download,fixup_dat)) - -define Download/fixup_cd_dat - FILE:=$(RPI_FIRMWARE_FILE)-fixup_cd.dat - URL:=$(RPI_FIRMWARE_URL) - URL_FILE:=fixup_cd.dat - HASH:=2d7c19e46780ef29867f8ed200a94bb77a7982f5bc41219afe864d2303ba3084 -endef -$(eval $(call Download,fixup_cd_dat)) - -define Download/fixup_x_dat - FILE:=$(RPI_FIRMWARE_FILE)-fixup_x.dat - URL:=$(RPI_FIRMWARE_URL) - URL_FILE:=fixup_x.dat - HASH:=692393562d0650f7d1891ba0143ad0500ccf07129947d386d56350e7ca204d16 -endef -$(eval $(call Download,fixup_x_dat)) - -define Download/fixup4_dat - FILE:=$(RPI_FIRMWARE_FILE)-fixup4.dat - URL:=$(RPI_FIRMWARE_URL) - URL_FILE:=fixup4.dat - HASH:=63a4a8f356e2b8ed2850d68b9adf21008ef1dfa7743b22ddc26987e4d3171302 -endef -$(eval $(call Download,fixup4_dat)) - -define Download/fixup4cd_dat - FILE:=$(RPI_FIRMWARE_FILE)-fixup4cd.dat - URL:=$(RPI_FIRMWARE_URL) - URL_FILE:=fixup4cd.dat - HASH:=2d7c19e46780ef29867f8ed200a94bb77a7982f5bc41219afe864d2303ba3084 -endef -$(eval $(call Download,fixup4cd_dat)) - -define Download/fixup4x_dat - FILE:=$(RPI_FIRMWARE_FILE)-fixup4x.dat - URL:=$(RPI_FIRMWARE_URL) - URL_FILE:=fixup4x.dat - HASH:=41328f6587c0cd47ae7fa7edab4bf62730dda54caf52ffaa3bfb24ff93b8348b -endef -$(eval $(call Download,fixup4x_dat)) - -define Download/start_elf - FILE:=$(RPI_FIRMWARE_FILE)-start.elf - URL:=$(RPI_FIRMWARE_URL) - URL_FILE:=start.elf - HASH:=8637fb847ff62f69fbb8b98b1beff685b47cf4095580e830724f6a27fb20fee0 -endef -$(eval $(call Download,start_elf)) - -define Download/start_cd_elf - FILE:=$(RPI_FIRMWARE_FILE)-start_cd.elf - URL:=$(RPI_FIRMWARE_URL) - URL_FILE:=start_cd.elf - HASH:=6832f57236f6c453cd72eac1f0ab53e265037fb75fc41301448fedb8d505f2b3 -endef -$(eval $(call Download,start_cd_elf)) - -define Download/start_x_elf - FILE:=$(RPI_FIRMWARE_FILE)-start_x.elf - URL:=$(RPI_FIRMWARE_URL) - URL_FILE:=start_x.elf - HASH:=6f72a3fda8cbdacb340676e18a8468b9edd89458173b5ecf3c12b00c147dce40 -endef -$(eval $(call Download,start_x_elf)) - -define Download/start4_elf - FILE:=$(RPI_FIRMWARE_FILE)-start4.elf - URL:=$(RPI_FIRMWARE_URL) - URL_FILE:=start4.elf - HASH:=badf4cd8822d1b85ad56ddb9e32e9b4220c88099c8cc0c3e70ae77190571c8ef -endef -$(eval $(call Download,start4_elf)) - -define Download/start4cd_elf - FILE:=$(RPI_FIRMWARE_FILE)-start4cd.elf - URL:=$(RPI_FIRMWARE_URL) - URL_FILE:=start4cd.elf - HASH:=7d3f13c8412c6b0efdbd3b53439776f3552621cc28ee887caaac539fb063ad8a -endef -$(eval $(call Download,start4cd_elf)) - -define Download/start4x_elf - FILE:=$(RPI_FIRMWARE_FILE)-start4x.elf - URL:=$(RPI_FIRMWARE_URL) - URL_FILE:=start4x.elf - HASH:=c30fbdfedad7180245ff567ccdea953fc1816d0da3ff4701b15071c6f8b47a89 -endef -$(eval $(call Download,start4x_elf)) +TAR_OPTIONS+=--strip-components 1 +TAR_CMD=$(HOST_TAR) -C $(1) $(TAR_OPTIONS) define Package/bcm27xx-gpu-fw SECTION:=boot @@ -136,51 +26,28 @@ define Package/bcm27xx-gpu-fw endef define Package/bcm27xx-gpu-fw/description - GPU and kernel boot firmware for bcm27xx. -endef - -define Build/Prepare - rm -rf $(PKG_BUILD_DIR) - mkdir -p $(PKG_BUILD_DIR) - $(CP) $(DL_DIR)/$(RPI_FIRMWARE_FILE)-LICENCE.broadcom $(PKG_BUILD_DIR)/LICENCE.broadcom - $(CP) $(DL_DIR)/$(RPI_FIRMWARE_FILE)-bootcode.bin $(PKG_BUILD_DIR)/bootcode.bin - $(CP) $(DL_DIR)/$(RPI_FIRMWARE_FILE)-fixup.dat $(PKG_BUILD_DIR)/fixup.dat - $(CP) $(DL_DIR)/$(RPI_FIRMWARE_FILE)-fixup_cd.dat $(PKG_BUILD_DIR)/fixup_cd.dat - $(CP) $(DL_DIR)/$(RPI_FIRMWARE_FILE)-fixup_x.dat $(PKG_BUILD_DIR)/fixup_x.dat - $(CP) $(DL_DIR)/$(RPI_FIRMWARE_FILE)-fixup4.dat $(PKG_BUILD_DIR)/fixup4.dat - $(CP) $(DL_DIR)/$(RPI_FIRMWARE_FILE)-fixup4cd.dat $(PKG_BUILD_DIR)/fixup4cd.dat - $(CP) $(DL_DIR)/$(RPI_FIRMWARE_FILE)-fixup4x.dat $(PKG_BUILD_DIR)/fixup4x.dat - $(CP) $(DL_DIR)/$(RPI_FIRMWARE_FILE)-start.elf $(PKG_BUILD_DIR)/start.elf - $(CP) $(DL_DIR)/$(RPI_FIRMWARE_FILE)-start_cd.elf $(PKG_BUILD_DIR)/start_cd.elf - $(CP) $(DL_DIR)/$(RPI_FIRMWARE_FILE)-start_x.elf $(PKG_BUILD_DIR)/start_x.elf - $(CP) $(DL_DIR)/$(RPI_FIRMWARE_FILE)-start4.elf $(PKG_BUILD_DIR)/start4.elf - $(CP) $(DL_DIR)/$(RPI_FIRMWARE_FILE)-start4cd.elf $(PKG_BUILD_DIR)/start4cd.elf - $(CP) $(DL_DIR)/$(RPI_FIRMWARE_FILE)-start4x.elf $(PKG_BUILD_DIR)/start4x.elf + GPU and kernel boot firmware for bcm27xx. endef define Build/Compile true endef -define Package/bcm27xx-gpu-fw/install - true -endef - define Build/InstallDev - $(CP) $(PKG_BUILD_DIR)/bootcode.bin $(KERNEL_BUILD_DIR) - $(CP) $(PKG_BUILD_DIR)/LICENCE.broadcom $(KERNEL_BUILD_DIR) - $(CP) $(PKG_BUILD_DIR)/start.elf $(KERNEL_BUILD_DIR) - $(CP) $(PKG_BUILD_DIR)/start_cd.elf $(KERNEL_BUILD_DIR) - $(CP) $(PKG_BUILD_DIR)/start_x.elf $(KERNEL_BUILD_DIR) - $(CP) $(PKG_BUILD_DIR)/start4.elf $(KERNEL_BUILD_DIR) - $(CP) $(PKG_BUILD_DIR)/start4cd.elf $(KERNEL_BUILD_DIR) - $(CP) $(PKG_BUILD_DIR)/start4x.elf $(KERNEL_BUILD_DIR) - $(CP) $(PKG_BUILD_DIR)/fixup.dat $(KERNEL_BUILD_DIR) - $(CP) $(PKG_BUILD_DIR)/fixup_cd.dat $(KERNEL_BUILD_DIR) - $(CP) $(PKG_BUILD_DIR)/fixup_x.dat $(KERNEL_BUILD_DIR) - $(CP) $(PKG_BUILD_DIR)/fixup4.dat $(KERNEL_BUILD_DIR) - $(CP) $(PKG_BUILD_DIR)/fixup4cd.dat $(KERNEL_BUILD_DIR) - $(CP) $(PKG_BUILD_DIR)/fixup4x.dat $(KERNEL_BUILD_DIR) + $(CP) $(PKG_BUILD_DIR)/boot/bootcode.bin $(KERNEL_BUILD_DIR) + $(CP) $(PKG_BUILD_DIR)/boot/LICENCE.broadcom $(KERNEL_BUILD_DIR) + $(CP) $(PKG_BUILD_DIR)/boot/start.elf $(KERNEL_BUILD_DIR) + $(CP) $(PKG_BUILD_DIR)/boot/start_cd.elf $(KERNEL_BUILD_DIR) + $(CP) $(PKG_BUILD_DIR)/boot/start_x.elf $(KERNEL_BUILD_DIR) + $(CP) $(PKG_BUILD_DIR)/boot/start4.elf $(KERNEL_BUILD_DIR) + $(CP) $(PKG_BUILD_DIR)/boot/start4cd.elf $(KERNEL_BUILD_DIR) + $(CP) $(PKG_BUILD_DIR)/boot/start4x.elf $(KERNEL_BUILD_DIR) + $(CP) $(PKG_BUILD_DIR)/boot/fixup.dat $(KERNEL_BUILD_DIR) + $(CP) $(PKG_BUILD_DIR)/boot/fixup_cd.dat $(KERNEL_BUILD_DIR) + $(CP) $(PKG_BUILD_DIR)/boot/fixup_x.dat $(KERNEL_BUILD_DIR) + $(CP) $(PKG_BUILD_DIR)/boot/fixup4.dat $(KERNEL_BUILD_DIR) + $(CP) $(PKG_BUILD_DIR)/boot/fixup4cd.dat $(KERNEL_BUILD_DIR) + $(CP) $(PKG_BUILD_DIR)/boot/fixup4x.dat $(KERNEL_BUILD_DIR) endef $(eval $(call BuildPackage,bcm27xx-gpu-fw)) From 538a1d740c5c79f081538239dea741cbc659cee3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Thu, 31 Oct 2024 10:09:44 +0100 Subject: [PATCH 18/27] bcm27xx: update to latest RPi patches MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The patches were generated from the RPi repo with the following command: git format-patch v6.6.58..rpi-6.6.y Signed-off-by: Álvaro Fernández Rojas --- target/linux/bcm27xx/bcm2708/config-6.6 | 1 + target/linux/bcm27xx/bcm2711/config-6.6 | 11 + target/linux/bcm27xx/bcm2712/config-6.6 | 11 + target/linux/bcm27xx/modules/sound.mk | 29 +- ...ssign-LBM-memory-during-atomic_flush.patch | 240 -- ...e-the-clear-of-SCALER_DISPBKGND_FILL.patch | 2 +- ...address-offset-for-planes-with-src_-.patch | 4 +- ...dd-hvs_dlist_allocs-debugfs-function.patch | 2 +- ...lanes-that-are-completely-off-screen.patch | 6 +- ...-dlist-alloc-immediately-if-it-never.patch | 4 +- ...moplet-have-different-register-offse.patch | 2 +- ...-Add-support-for-D0-register-changes.patch | 16 +- ...-to-support-D0-alpha-and-csc-changes.patch | 10 +- ...12-support-to-vc4_plane_async_set_fb.patch | 6 +- ...ic_async_check-to-call-the-right-mod.patch | 2 +- ...-planes-that-have-0-destination-size.patch | 6 +- ...port-fixed-alpha-correctly-on-2712D0.patch | 4 +- ...hvs-Fix-lbm-size-calculation-for-yuv.patch | 2 +- ...g_fill-if-there-are-no-planes-enable.patch | 4 +- ...on-to-call-from-crtc-to-encoder-on-v.patch | 2 +- ...I-before-issuing-a-cache-flush-comma.patch | 35 - ...ct-posted-write-counts-for-SD-cards-.patch | 2 +- ...the-2pixel-clock-odd-timings-workaro.patch | 2 +- ...th-hci_sync-Fix-crash-on-NULL-parent.patch | 27 + ...rlay-for-generic-I2S-clock-master-DA.patch | 96 + ...ro-put-ADC-control-definitions-in-he.patch | 275 ++ ...Add-DRM_FORMAT_ARGB8888-and-DRM_FORM.patch | 48 + ...Add-DRM_FORMAT_ARGB8888-and-DRM_FORM.patch | 48 + ...Add-DRM_FORMAT_ARGB8888-and-DRM_FORM.patch | 48 + ...elay-after-disabling-hdmi-phy-output.patch | 34 + ...m-vc4-Implement-vc6_hdmi_phy_disable.patch | 25 + ...er-down-the-PLL-core-when-resetting-.patch | 35 + ...r-for-new-HiFiBerry-ADC-only-board-s.patch | 228 ++ ...erlays-Add-overlay-for-Hifiberry-ADC.patch | 100 + ...ev-Restore-loading-from-Device-Tree.patch} | 18 +- ...dsi-Implement-more-DSI-options-and-f.patch | 242 ++ ...oscillator-stop-bit-handling-reading.patch | 53 + ...i-Update-Hailo-accelerator-device-dr.patch | 3352 +++++++++++++++++ ...d-Make-SPS-PPS-optional-in-a-request.patch | 80 + ...en-overlay-Add-invert-x-y-and-swapxy.patch | 37 + ...panel-Added-waveshare-5.0inch-6.25in.patch | 82 + ...s-overlays-Added-waveshare-5.0inch-6.patch | 27 + ...s-overlays-Added-waveshare-5.0inch-6.patch | 23 + ...bridge-Add-debugfs-progress-indicato.patch | 89 + ...edia-dt-bindings-i2c-Add-Sony-IMX500.patch | 166 + ...2c-Add-driver-for-Sony-IMX500-sensor.patch | 1675 ++++++++ ...rlycpio-export-symbol-find_cpio_data.patch | 20 + ...-imx500-Inbuilt-AI-processor-support.patch | 1631 ++++++++ ...s-bcm-283x-2712-clocks-as-simple-bus.patch | 41 + .../950-1248-dts-Add-AI-Camera-support.patch | 389 ++ ...x500-Enable-LED-during-SPI-transfers.patch | 66 + ...io-bridge-add-missing-MD5-dependency.patch | 24 + ...vec-Increase-width-limit-for-PAL-16-.patch | 50 + ...Always-request-for-user-confirmatio.patch} | 8 +- ...v5647-Add-control-of-V4L2_CID_HBLANK.patch | 126 + ...ort-for-per-plane-scaling-filter-sel.patch | 170 + ...are-Remove-duplicated-sentinel-on-co.patch | 37 + ...le-write-caching-on-Samsung-2023-mo.patch} | 4 +- ...n-Maintain-TLB-coherency-in-LRU-code.patch | 27 + ...1-Correct-symmetry-on-enable-disable.patch | 35 + ...the-definitions-for-the-HiFiBerry-8-.patch | 113 + ...ry-ADC8x-8-channel-ADC-to-simple-car.patch | 88 + ...dec-Allocate-the-max-number-of-buffe.patch | 35 + ...rpolate-bit-for-nearest-neighbour-fi.patch | 26 + ...-dts-rp1-Disable-DMA-usage-for-UART0.patch | 34 + ...edia-imx500-Fixes-for-vblank-control.patch | 50 + ...ent-bridge-init-order-with-pre_enabl.patch | 56 + ...-t-reset-the-host-until-post_disable.patch | 50 + ...le-video-and-then-retry-failed-trans.patch | 111 + ...1-Add-option-to-reconfigure-setup-co.patch | 102 + ...gulator-rpi-panel-Remove-the-ID-read.patch | 90 + ...ehat-Add-Raspberry-Pi-Sense-HAT-to-s.patch | 29 + ...rrect-pinctrl-assignment-on-mcp23017.patch | 24 + ...-Also-unregister-pl011_axi_platform_.patch | 22 + ...8960-soundcard-Fix-clock-declaration.patch | 62 + ...ix-playback-muting-when-recording-is.patch | 44 + ...-i2s-Set-the-PERIOD_BYTES-min-to-256.patch | 48 + ...-rp1-Don-t-crash-on-duplicate-clocks.patch | 30 + ...x500-Simplify-the-vblank-control-ini.patch | 98 + ...verlay_map-ramoops-pi4-works-on-Pi-5.patch | 28 + ...R-allocation-on-bcm2711-and-bcm2712-.patch | 109 + ...ays-Add-Pineboards-HatDrive-POE-6257.patch | 61 + ...ct-vc4-kms-dpi-generic-for-width-hei.patch | 31 + ...rpi-Add-four-missing-GPIOs-to-2712D0.patch | 32 + ...-Add-preliminary-bcm2712-rpi-500-dts.patch | 169 + ...2712-Reduce-default-cma-usage-on-Pi5.patch | 30 + ...2d0-Add-non-d0-vc6-compatible-string.patch | 39 + ...ys-Convert-SenseHAT-overlays-to-use-.patch | 100 + ...Remove-downstream-SenseHAT-core-and-.patch | 608 +++ ...nsehat-joystick-Revert-to-downstream.patch | 22 + ...-dtoverlays-Add-Sense-Hat-to-hat_map.patch | 27 + ...-hat_map-Add-Sense-and-Hailo-AI-HATs.patch | 54 + ...rs-media-imx500-Enable-LS-correction.patch | 408 ++ ...m2712-rpi-500-Add-USER_LED-GPIO-name.patch | 23 + ...p-imx500-overlays-to-have-unique-clo.patch | 86 + ...n-overlay-for-Waveshare-s-800x480-4..patch | 177 + ...equest-for-min-clocks-when-hdmi-outp.patch | 74 + ...rpi-Add-aliases-for-the-CSI-DSI-I2Cs.patch | 71 + ...edia-video-mux-Propagate-controls-to.patch | 51 + ...platform-video-mux-Fix-mutex-locking.patch | 59 + ...-Tidy-up-mode-registers-to-make-the-.patch | 94 + ...47-Separate-out-the-common-registers.patch | 392 ++ ...-Use-the-same-PLL-config-for-full-10.patch | 53 + ...-Add-V4L2_CID_LINK_FREQUENCY-control.patch | 111 + ...erence-requests-after-finishing-them.patch | 71 + ...le-cache-on-more-known-bad-Sandisk-c.patch | 35 + ...e-CQ-on-SD-cards-when-doing-non-Disc.patch | 55 + ...able-SD-slot-CQE-by-default-on-Pi-5.patch} | 12 +- ...MC_QUIRK_BROKEN_ERASE-for-Phison-Int.patch | 33 + ...pad-avoid-repeatedly-converting-GPIO.patch | 155 + ...ma-Add-simple-generic-NUMA-emulation.patch | 182 + ...64-numa-Add-NUMA-emulation-for-ARM64.patch | 39 + ...erride-of-kernel-s-default-NUMA-poli.patch | 115 + ...eap-Allow-specifying-maximum-allocat.patch | 46 + ...heck-emulated-zones-around-the-CMA-w.patch | 95 + ...e-common-rpi-settings-into-rpi-files.patch | 97 + ...t-preferred-numa-options-in-bootargs.patch | 52 + ...nclude-writeback-conn-load-in-load-t.patch | 48 + ...nic-priority-for-writeback-connector.patch | 54 + .../950-1348-dts-Simplify-bootargs.patch | 112 + ...l-command-line-to-disable-memory-cgr.patch | 193 + ...Sort-out-CM5-and-I-O-board-I2C-ports.patch | 185 + 122 files changed, 15104 insertions(+), 335 deletions(-) delete mode 100644 target/linux/bcm27xx/patches-6.6/950-0635-drm-vc4-Assign-LBM-memory-during-atomic_flush.patch delete mode 100644 target/linux/bcm27xx/patches-6.6/950-1115-mmc-sd-halt-CQHCI-before-issuing-a-cache-flush-comma.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1218-Bluetooth-hci_sync-Fix-crash-on-NULL-parent.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1219-overlays-add-overlay-for-generic-I2S-clock-master-DA.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1220-ASoC-DACplusADCPro-put-ADC-control-definitions-in-he.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1222-drm-rp1-rp1-dsi-Add-DRM_FORMAT_ARGB8888-and-DRM_FORM.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1223-drm-rp1-rp1-dpi-Add-DRM_FORMAT_ARGB8888-and-DRM_FORM.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1224-drm-rp1-rp1-vec-Add-DRM_FORMAT_ARGB8888-and-DRM_FORM.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1225-drm-vc4-Add-a-delay-after-disabling-hdmi-phy-output.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1226-drm-vc4-Implement-vc6_hdmi_phy_disable.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1227-drm-vc4-Also-power-down-the-PLL-core-when-resetting-.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1228-ASoC-add-driver-for-new-HiFiBerry-ADC-only-board-s.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1229-overlays-Add-overlay-for-Hifiberry-ADC.patch rename target/linux/bcm27xx/patches-6.6/{950-0320-spi-spidev-Restore-loading-from-Device-Tree.patch => 950-1232-spi-spidev-Restore-loading-from-Device-Tree.patch} (60%) create mode 100644 target/linux/bcm27xx/patches-6.6/950-1233-drivers-drm-rp1-dsi-Implement-more-DSI-options-and-f.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1234-rtc-pcf8523-Fix-oscillator-stop-bit-handling-reading.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1235-drivers-media-pci-Update-Hailo-accelerator-device-dr.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1236-media-rpivid-Make-SPS-PPS-optional-in-a-request.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1238-piscreen-overlay-Add-invert-x-y-and-swapxy.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1239-drivers-gpu-drm-panel-Added-waveshare-5.0inch-6.25in.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1240-arch-arm-boot-dts-overlays-Added-waveshare-5.0inch-6.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1241-arch-arm-boot-dts-overlays-Added-waveshare-5.0inch-6.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1242-spi-rp2040-gpio-bridge-Add-debugfs-progress-indicato.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1243-media-dt-bindings-i2c-Add-Sony-IMX500.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1244-media-i2c-Add-driver-for-Sony-IMX500-sensor.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1245-lib-earlycpio-export-symbol-find_cpio_data.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1246-media-i2c-imx500-Inbuilt-AI-processor-support.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1247-dts-bcm-283x-2712-clocks-as-simple-bus.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1248-dts-Add-AI-Camera-support.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1250-media-i2c-imx500-Enable-LED-during-SPI-transfers.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1251-spi-rp2040-gpio-bridge-add-missing-MD5-dependency.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1252-drivers-drm-rp1-vec-Increase-width-limit-for-PAL-16-.patch rename target/linux/bcm27xx/patches-6.6/{950-0058-Revert-Bluetooth-Always-request-for-user-confirmatio.patch => 950-1255-Revert-Bluetooth-Always-request-for-user-confirmatio.patch} (86%) create mode 100644 target/linux/bcm27xx/patches-6.6/950-1256-media-i2c-ov5647-Add-control-of-V4L2_CID_HBLANK.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1257-drm-vc4-Add-support-for-per-plane-scaling-filter-sel.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1258-drm-panel-waveshare-Remove-duplicated-sentinel-on-co.patch rename target/linux/bcm27xx/patches-6.6/{950-1019-drivers-mmc-disable-write-caching-on-Samsung-2023-mo.patch => 950-1260-drivers-mmc-disable-write-caching-on-Samsung-2023-mo.patch} (92%) create mode 100644 target/linux/bcm27xx/patches-6.6/950-1261-mm-vmscan-Maintain-TLB-coherency-in-LRU-code.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1262-drm-panel-ili9881-Correct-symmetry-on-enable-disable.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1263-dtoverlays-adds-the-definitions-for-the-HiFiBerry-8-.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1264-ASoC-add-HiFiBerry-ADC8x-8-channel-ADC-to-simple-car.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1265-vc04_services-codec-Allocate-the-max-number-of-buffe.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1266-drm-vc4-Fix-interpolate-bit-for-nearest-neighbour-fi.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1267-dts-rp1-Disable-DMA-usage-for-UART0.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1269-drivers-media-imx500-Fixes-for-vblank-control.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1270-drm-bridge-Document-bridge-init-order-with-pre_enabl.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1271-drm-vc4-dsi-Don-t-reset-the-host-until-post_disable.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1272-drm-vc4-dsi-enable-video-and-then-retry-failed-trans.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1273-drm-panel-ili9881-Add-option-to-reconfigure-setup-co.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1274-regulator-rpi-panel-Remove-the-ID-read.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1275-drivers-mfd-sensehat-Add-Raspberry-Pi-Sense-HAT-to-s.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1281-dtoverlays-Correct-pinctrl-assignment-on-mcp23017.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1282-tty-serial-pl011-Also-unregister-pl011_axi_platform_.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1283-overlays-wm8960-soundcard-Fix-clock-declaration.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1284-googlevoicehat-Fix-playback-muting-when-recording-is.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1285-ASoC-bcm2835-i2s-Set-the-PERIOD_BYTES-min-to-256.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1286-clk-clk-rp1-Don-t-crash-on-duplicate-clocks.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1287-drivers-media-imx500-Simplify-the-vblank-control-ini.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1288-dts-overlay_map-ramoops-pi4-works-on-Pi-5.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1289-dts-align-PCI-BAR-allocation-on-bcm2711-and-bcm2712-.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1290-overlays-Add-Pineboards-HatDrive-POE-6257.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1296-dtoverlays-Correct-vc4-kms-dpi-generic-for-width-hei.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1297-dts-bcm2712-rpi-Add-four-missing-GPIOs-to-2712D0.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1298-arm64-dts-Add-preliminary-bcm2712-rpi-500-dts.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1301-dts-2712-Reduce-default-cma-usage-on-Pi5.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1305-dts-bcm2712d0-Add-non-d0-vc6-compatible-string.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1312-Reapply-dtoverlays-Convert-SenseHAT-overlays-to-use-.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1313-Reapply-drivers-Remove-downstream-SenseHAT-core-and-.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1315-Reapply-Input-sensehat-joystick-Revert-to-downstream.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1316-Reapply-dtoverlays-Add-Sense-Hat-to-hat_map.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1317-overlays-hat_map-Add-Sense-and-Hailo-AI-HATs.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1318-drivers-media-imx500-Enable-LS-correction.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1319-dts-bcm2712-rpi-500-Add-USER_LED-GPIO-name.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1321-dtoverlays-Fix-up-imx500-overlays-to-have-unique-clo.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1322-dtoverlays-Add-an-overlay-for-Waveshare-s-800x480-4..patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1323-drm-vc4-Remove-request-for-min-clocks-when-hdmi-outp.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1324-dts-bcm2712-rpi-Add-aliases-for-the-CSI-DSI-I2Cs.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1325-NotForUpstream-media-video-mux-Propagate-controls-to.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1326-media-platform-video-mux-Fix-mutex-locking.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1327-media-i2c-ov5647-Tidy-up-mode-registers-to-make-the-.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1328-media-i2c-ov5647-Separate-out-the-common-registers.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1329-media-i2c-ov5647-Use-the-same-PLL-config-for-full-10.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1330-media-i2c-ov5647-Add-V4L2_CID_LINK_FREQUENCY-control.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1331-mmc-don-t-reference-requests-after-finishing-them.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1333-mmc-quirks-disable-cache-on-more-known-bad-Sandisk-c.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1334-mmc-block-disable-CQ-on-SD-cards-when-doing-non-Disc.patch rename target/linux/bcm27xx/patches-6.6/{950-1208-DTS-bcm2712-enable-SD-slot-CQE-by-default-on-Pi-5.patch => 950-1335-DTS-bcm2712-re-enable-SD-slot-CQE-by-default-on-Pi-5.patch} (77%) create mode 100644 target/linux/bcm27xx/patches-6.6/950-1336-mmc-quirks-add-MMC_QUIRK_BROKEN_ERASE-for-Phison-Int.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1337-Input-matrix_keypad-avoid-repeatedly-converting-GPIO.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1338-numa-Add-simple-generic-NUMA-emulation.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1339-arm64-numa-Add-NUMA-emulation-for-ARM64.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1340-mm-numa-Allow-override-of-kernel-s-default-NUMA-poli.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1341-dma-buf-system_heap-Allow-specifying-maximum-allocat.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1342-numa-emulation-Check-emulated-zones-around-the-CMA-w.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1344-dts-Move-some-common-rpi-settings-into-rpi-files.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1345-dts-Set-preferred-numa-options-in-bootargs.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1346-drm-vc4-Do-not-include-writeback-conn-load-in-load-t.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1347-drm-vc4-Drop-panic-priority-for-writeback-connector.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1348-dts-Simplify-bootargs.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1349-cgroup-Use-kernel-command-line-to-disable-memory-cgr.patch create mode 100644 target/linux/bcm27xx/patches-6.6/950-1350-arm64-dts-Sort-out-CM5-and-I-O-board-I2C-ports.patch diff --git a/target/linux/bcm27xx/bcm2708/config-6.6 b/target/linux/bcm27xx/bcm2708/config-6.6 index a50596e45e6..4872e44642f 100644 --- a/target/linux/bcm27xx/bcm2708/config-6.6 +++ b/target/linux/bcm27xx/bcm2708/config-6.6 @@ -160,6 +160,7 @@ CONFIG_FIX_EARLYCON_MEM=y CONFIG_FONT_8x16=y CONFIG_FONT_8x8=y CONFIG_FONT_SUPPORT=y +CONFIG_FORCE_NR_CPUS=y CONFIG_FRAMEBUFFER_CONSOLE=y # CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y diff --git a/target/linux/bcm27xx/bcm2711/config-6.6 b/target/linux/bcm27xx/bcm2711/config-6.6 index 33458c27d72..270763549a1 100644 --- a/target/linux/bcm27xx/bcm2711/config-6.6 +++ b/target/linux/bcm27xx/bcm2711/config-6.6 @@ -176,6 +176,7 @@ CONFIG_DMA_BCM2835=y CONFIG_DMA_CMA=y CONFIG_DMA_DIRECT_REMAP=y CONFIG_DMA_ENGINE=y +# CONFIG_DMA_NUMA_CMA is not set CONFIG_DMA_OF=y CONFIG_DMA_SHARED_BUFFER=y CONFIG_DMA_VIRTUAL_CHANNELS=y @@ -221,6 +222,8 @@ CONFIG_FW_LOADER_SYSFS=y CONFIG_GCC10_NO_ARRAY_BOUNDS=y CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS=y CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_ARCH_NUMA=y +CONFIG_GENERIC_ARCH_NUMA_EMULATION=y CONFIG_GENERIC_ARCH_TOPOLOGY=y CONFIG_GENERIC_BUG=y CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y @@ -331,6 +334,8 @@ CONFIG_MODULES_USE_ELF_RELA=y # CONFIG_MTD is not set CONFIG_MUTEX_SPIN_ON_OWNER=y CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y +CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y CONFIG_NEED_SG_DMA_LENGTH=y CONFIG_NET_EGRESS=y CONFIG_NET_FLOW_LIMIT=y @@ -340,11 +345,15 @@ CONFIG_NET_SELFTESTS=y CONFIG_NET_XGRESS=y CONFIG_NLS=y CONFIG_NLS_ASCII=y +CONFIG_NODES_SHIFT=4 CONFIG_NOP_USB_XCEIV=y CONFIG_NO_HZ=y CONFIG_NO_HZ_COMMON=y CONFIG_NO_HZ_IDLE=y CONFIG_NR_CPUS=4 +CONFIG_NUMA=y +# CONFIG_NUMA_BALANCING is not set +CONFIG_NUMA_EMULATION=y CONFIG_NVMEM=y CONFIG_NVMEM_LAYOUTS=y CONFIG_NVMEM_RASPBERRYPI_OTP=y @@ -358,6 +367,7 @@ CONFIG_OF_GPIO=y CONFIG_OF_IRQ=y CONFIG_OF_KOBJ=y CONFIG_OF_MDIO=y +CONFIG_OF_NUMA=y CONFIG_OF_OVERLAY=y CONFIG_OF_RESOLVE=y CONFIG_PADATA=y @@ -485,6 +495,7 @@ CONFIG_USB_UAS=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_PCI=y CONFIG_USB_XHCI_PLATFORM=y +CONFIG_USE_PERCPU_NUMA_NODE_ID=y CONFIG_VCHIQ_CDEV=y CONFIG_VIDEO_CMDLINE=y CONFIG_VIDEO_DEV=y diff --git a/target/linux/bcm27xx/bcm2712/config-6.6 b/target/linux/bcm27xx/bcm2712/config-6.6 index 734b19612bc..a5eb6c4d0e1 100644 --- a/target/linux/bcm27xx/bcm2712/config-6.6 +++ b/target/linux/bcm27xx/bcm2712/config-6.6 @@ -218,6 +218,7 @@ CONFIG_DMA_BCM2835=y CONFIG_DMA_CMA=y CONFIG_DMA_DIRECT_REMAP=y CONFIG_DMA_ENGINE=y +# CONFIG_DMA_NUMA_CMA is not set CONFIG_DMA_OF=y CONFIG_DMA_OPS=y CONFIG_DMA_SHARED_BUFFER=y @@ -264,6 +265,8 @@ CONFIG_FW_LOADER_SYSFS=y CONFIG_GCC10_NO_ARRAY_BOUNDS=y CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS=y CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_ARCH_NUMA=y +CONFIG_GENERIC_ARCH_NUMA_EMULATION=y CONFIG_GENERIC_ARCH_TOPOLOGY=y CONFIG_GENERIC_BUG=y CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y @@ -409,6 +412,8 @@ CONFIG_MMU_LAZY_TLB_REFCOUNT=y CONFIG_MODULES_USE_ELF_RELA=y CONFIG_MUTEX_SPIN_ON_OWNER=y CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y +CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y CONFIG_NEED_SG_DMA_FLAGS=y CONFIG_NEED_SG_DMA_LENGTH=y CONFIG_NET_EGRESS=y @@ -419,11 +424,15 @@ CONFIG_NET_SELFTESTS=y CONFIG_NET_XGRESS=y CONFIG_NLS=y CONFIG_NLS_ASCII=y +CONFIG_NODES_SHIFT=4 CONFIG_NOP_USB_XCEIV=y CONFIG_NO_HZ=y CONFIG_NO_HZ_COMMON=y CONFIG_NO_HZ_IDLE=y CONFIG_NR_CPUS=4 +CONFIG_NUMA=y +# CONFIG_NUMA_BALANCING is not set +CONFIG_NUMA_EMULATION=y CONFIG_NVMEM=y CONFIG_NVMEM_LAYOUTS=y CONFIG_NVMEM_RASPBERRYPI_OTP=y @@ -441,6 +450,7 @@ CONFIG_OF_IOMMU=y CONFIG_OF_IRQ=y CONFIG_OF_KOBJ=y CONFIG_OF_MDIO=y +CONFIG_OF_NUMA=y CONFIG_OF_OVERLAY=y CONFIG_OF_RESOLVE=y CONFIG_PADATA=y @@ -610,6 +620,7 @@ CONFIG_USB_UAS=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_PCI=y CONFIG_USB_XHCI_PLATFORM=y +CONFIG_USE_PERCPU_NUMA_NODE_ID=y CONFIG_VCHIQ_CDEV=y CONFIG_VIDEO_CMDLINE=y CONFIG_VIDEO_DEV=y diff --git a/target/linux/bcm27xx/modules/sound.mk b/target/linux/bcm27xx/modules/sound.mk index e61f07852b6..989828e97ee 100644 --- a/target/linux/bcm27xx/modules/sound.mk +++ b/target/linux/bcm27xx/modules/sound.mk @@ -45,7 +45,8 @@ $(eval $(call KernelPackage,sound-soc-bcm2835-i2s)) define KernelPackage/sound-soc-rpi-simple-soundcard TITLE:=Support for Raspberry Pi simple soundcards KCONFIG:= \ - CONFIG_SND_RPI_SIMPLE_SOUNDCARD + CONFIG_SND_RPI_SIMPLE_SOUNDCARD \ + CONFIG_SND_BCM2708_SOC_HIFIBERRY_ADC8X FILES:= \ $(LINUX_DIR)/sound/soc/bcm/snd-soc-rpi-simple-soundcard.ko AUTOLOAD:=$(call AutoLoad,68,snd-soc-rpi-simple-soundcard) @@ -526,6 +527,32 @@ endef $(eval $(call KernelPackage,sound-soc-googlevoicehat)) +define KernelPackage/sound-soc-hifiberry-adc + TITLE:=Support for HifiBerry ADC + KCONFIG:= \ + CONFIG_SND_BCM2708_SOC_HIFIBERRY_ADC \ + CONFIG_SND_RPI_HIFIBERRY_ADC \ + CONFIG_SND_SOC_PCM186X_I2C + FILES:= \ + $(LINUX_DIR)/sound/soc/bcm/snd-soc-hifiberry-adc.ko \ + $(LINUX_DIR)/sound/soc/codecs/snd-soc-pcm186x.ko \ + $(LINUX_DIR)/sound/soc/codecs/snd-soc-pcm186x-i2c.ko + AUTOLOAD:=$(call AutoLoad,68,snd-soc-pcm186x snd-soc-pcm186x-i2c \ + snd-soc-hifiberry-adc) + DEPENDS:= \ + kmod-sound-soc-bcm2835-i2s \ + +kmod-i2c-bcm2835 \ + +kmod-regmap-i2c + $(call AddDepends/sound) +endef + +define KernelPackage/sound-soc-hifiberry-adc/description + This package contains support for HifiBerry ADC +endef + +$(eval $(call KernelPackage,sound-soc-hifiberry-adc)) + + define KernelPackage/sound-soc-hifiberry-dac TITLE:=Support for HifiBerry DAC KCONFIG:= \ diff --git a/target/linux/bcm27xx/patches-6.6/950-0635-drm-vc4-Assign-LBM-memory-during-atomic_flush.patch b/target/linux/bcm27xx/patches-6.6/950-0635-drm-vc4-Assign-LBM-memory-during-atomic_flush.patch deleted file mode 100644 index ccdae3dbe06..00000000000 --- a/target/linux/bcm27xx/patches-6.6/950-0635-drm-vc4-Assign-LBM-memory-during-atomic_flush.patch +++ /dev/null @@ -1,240 +0,0 @@ -From c7b98a63328a749d44b7580ee9baafc5d417e48f Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 31 Aug 2023 11:45:38 +0100 -Subject: [PATCH 0635/1085] drm/vc4: Assign LBM memory during atomic_flush. - -Avoid double buffering LBM allocations by making the -allocation a single alloc per crtc at atomic_flush. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/tests/vc4_test_lbm_size.c | 2 +- - drivers/gpu/drm/vc4/vc4_drv.h | 8 ++-- - drivers/gpu/drm/vc4/vc4_hvs.c | 47 ++++++++++++++++++- - drivers/gpu/drm/vc4/vc4_plane.c | 38 +++------------ - 4 files changed, 58 insertions(+), 37 deletions(-) - ---- a/drivers/gpu/drm/vc4/tests/vc4_test_lbm_size.c -+++ b/drivers/gpu/drm/vc4/tests/vc4_test_lbm_size.c -@@ -248,7 +248,7 @@ static void drm_vc4_test_vc4_lbm_size(st - ret = drm_atomic_check_only(state); - KUNIT_ASSERT_EQ(test, ret, 0); - -- KUNIT_EXPECT_EQ(test, vc4_plane_state->lbm.size, params->expected_lbm_size); -+ KUNIT_EXPECT_EQ(test, vc4_plane_state->lbm_size, params->expected_lbm_size); - - for (i = 0; i < 2; i++) { - KUNIT_EXPECT_EQ(test, ---- a/drivers/gpu/drm/vc4/vc4_drv.h -+++ b/drivers/gpu/drm/vc4/vc4_drv.h -@@ -417,6 +417,8 @@ struct vc4_plane_state { - u32 dlist_size; /* Number of dwords allocated for the display list */ - u32 dlist_count; /* Number of used dwords in the display list. */ - -+ u32 lbm_size; /* LBM requirements for this plane */ -+ - /* Offset in the dlist to various words, for pageflip or - * cursor updates. - */ -@@ -442,9 +444,6 @@ struct vc4_plane_state { - bool is_unity; - bool is_yuv; - -- /* Our allocation in LBM for temporary storage during scaling. */ -- struct drm_mm_node lbm; -- - /* Our allocation in UPM for prefetching. */ - struct drm_mm_node upm[DRM_FORMAT_MAX_PLANES]; - -@@ -635,6 +634,9 @@ struct vc4_crtc { - * access to that value. - */ - unsigned int current_hvs_channel; -+ -+ /* @lbm: Our allocation in LBM for temporary storage during scaling. */ -+ struct drm_mm_node lbm; - }; - - #define to_vc4_crtc(_crtc) \ ---- a/drivers/gpu/drm/vc4/vc4_hvs.c -+++ b/drivers/gpu/drm/vc4/vc4_hvs.c -@@ -1103,6 +1103,7 @@ int vc4_hvs_atomic_check(struct drm_crtc - struct drm_plane *plane; - const struct drm_plane_state *plane_state; - u32 dlist_count = 0; -+ u32 lbm_count = 0; - - /* The pixelvalve can only feed one encoder (and encoders are - * 1:1 with connectors.) -@@ -1111,6 +1112,8 @@ int vc4_hvs_atomic_check(struct drm_crtc - return -EINVAL; - - drm_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) { -+ const struct vc4_plane_state *vc4_plane_state = -+ to_vc4_plane_state(plane_state); - u32 plane_dlist_count = vc4_plane_dlist_size(plane_state); - - drm_dbg_driver(dev, "[CRTC:%d:%s] Found [PLANE:%d:%s] with DLIST size: %u\n", -@@ -1119,6 +1122,7 @@ int vc4_hvs_atomic_check(struct drm_crtc - plane_dlist_count); - - dlist_count += plane_dlist_count; -+ lbm_count += vc4_plane_state->lbm_size; - } - - dlist_count++; /* Account for SCALER_CTL0_END. */ -@@ -1132,6 +1136,8 @@ int vc4_hvs_atomic_check(struct drm_crtc - - vc4_state->mm = alloc; - -+ /* FIXME: Check total lbm allocation here */ -+ - return vc4_hvs_gamma_check(crtc, state); - } - -@@ -1246,7 +1252,10 @@ void vc4_hvs_atomic_flush(struct drm_crt - bool debug_dump_regs = false; - bool enable_bg_fill = false; - u32 __iomem *dlist_start, *dlist_next; -+ unsigned long irqflags; - unsigned int zpos = 0; -+ u32 lbm_offset = 0; -+ u32 lbm_size = 0; - bool found = false; - int idx; - -@@ -1265,6 +1274,35 @@ void vc4_hvs_atomic_flush(struct drm_crt - vc4_hvs_dump_state(hvs); - } - -+ drm_atomic_crtc_for_each_plane(plane, crtc) { -+ vc4_plane_state = to_vc4_plane_state(plane->state); -+ lbm_size += vc4_plane_state->lbm_size; -+ } -+ -+ if (drm_mm_node_allocated(&vc4_crtc->lbm)) { -+ spin_lock_irqsave(&vc4_crtc->irq_lock, irqflags); -+ drm_mm_remove_node(&vc4_crtc->lbm); -+ spin_unlock_irqrestore(&vc4_crtc->irq_lock, irqflags); -+ } -+ -+ if (lbm_size) { -+ int ret; -+ -+ spin_lock_irqsave(&vc4_crtc->irq_lock, irqflags); -+ ret = drm_mm_insert_node_generic(&vc4->hvs->lbm_mm, -+ &vc4_crtc->lbm, -+ lbm_size, 1, -+ 0, 0); -+ spin_unlock_irqrestore(&vc4_crtc->irq_lock, irqflags); -+ -+ if (ret) { -+ pr_err("Failed to allocate LBM ret %d\n", ret); -+ return; -+ } -+ } -+ -+ lbm_offset = vc4_crtc->lbm.start; -+ - dlist_start = vc4->hvs->dlist + vc4_state->mm->mm_node.start; - dlist_next = dlist_start; - -@@ -1276,6 +1314,8 @@ void vc4_hvs_atomic_flush(struct drm_crt - if (plane->state->normalized_zpos != zpos) - continue; - -+ vc4_plane_state = to_vc4_plane_state(plane->state); -+ - /* Is this the first active plane? */ - if (dlist_next == dlist_start) { - /* We need to enable background fill when a plane -@@ -1286,10 +1326,15 @@ void vc4_hvs_atomic_flush(struct drm_crt - * already needs it or all planes on top blend from - * the first or a lower plane. - */ -- vc4_plane_state = to_vc4_plane_state(plane->state); - enable_bg_fill = vc4_plane_state->needs_bg_fill; - } - -+ if (vc4_plane_state->lbm_size) { -+ vc4_plane_state->dlist[vc4_plane_state->lbm_offset] = -+ lbm_offset; -+ lbm_offset += vc4_plane_state->lbm_size; -+ } -+ - dlist_next += vc4_plane_write_dlist(plane, dlist_next); - - found = true; ---- a/drivers/gpu/drm/vc4/vc4_plane.c -+++ b/drivers/gpu/drm/vc4/vc4_plane.c -@@ -288,7 +288,6 @@ struct drm_plane_state *vc4_plane_duplic - if (!vc4_state) - return NULL; - -- memset(&vc4_state->lbm, 0, sizeof(vc4_state->lbm)); - memset(&vc4_state->upm, 0, sizeof(vc4_state->upm)); - - for (i = 0; i < DRM_FORMAT_MAX_PLANES; i++) -@@ -320,14 +319,6 @@ void vc4_plane_destroy_state(struct drm_ - struct vc4_plane_state *vc4_state = to_vc4_plane_state(state); - unsigned int i; - -- if (drm_mm_node_allocated(&vc4_state->lbm)) { -- unsigned long irqflags; -- -- spin_lock_irqsave(&hvs->mm_lock, irqflags); -- drm_mm_remove_node(&vc4_state->lbm); -- spin_unlock_irqrestore(&hvs->mm_lock, irqflags); -- } -- - for (i = 0; i < DRM_FORMAT_MAX_PLANES; i++) { - unsigned long irqflags; - -@@ -903,12 +894,13 @@ static int vc4_plane_allocate_lbm(struct - struct vc4_dev *vc4 = to_vc4_dev(drm); - struct drm_plane *plane = state->plane; - struct vc4_plane_state *vc4_state = to_vc4_plane_state(state); -- unsigned long irqflags; - u32 lbm_size; - - lbm_size = vc4_lbm_size(state); -- if (!lbm_size) -+ if (!lbm_size) { -+ vc4_state->lbm_size = 0; - return 0; -+ } - - /* - * NOTE: BCM2712 doesn't need to be aligned, since the size -@@ -925,28 +917,10 @@ static int vc4_plane_allocate_lbm(struct - if (WARN_ON(!vc4_state->lbm_offset)) - return -EINVAL; - -- /* Allocate the LBM memory that the HVS will use for temporary -- * storage due to our scaling/format conversion. -+ /* FIXME: Add loop here that ensures that the total LBM assigned in this -+ * state is less than the total lbm size - */ -- if (!drm_mm_node_allocated(&vc4_state->lbm)) { -- int ret; -- -- spin_lock_irqsave(&vc4->hvs->mm_lock, irqflags); -- ret = drm_mm_insert_node_generic(&vc4->hvs->lbm_mm, -- &vc4_state->lbm, -- lbm_size, 1, -- 0, 0); -- spin_unlock_irqrestore(&vc4->hvs->mm_lock, irqflags); -- -- if (ret) { -- drm_err(drm, "Failed to allocate LBM entry: %d\n", ret); -- return ret; -- } -- } else { -- WARN_ON_ONCE(lbm_size != vc4_state->lbm.size); -- } -- -- vc4_state->dlist[vc4_state->lbm_offset] = vc4_state->lbm.start; -+ vc4_state->lbm_size = lbm_size; - - return 0; - } diff --git a/target/linux/bcm27xx/patches-6.6/950-0655-vc4-drm-Remove-the-clear-of-SCALER_DISPBKGND_FILL.patch b/target/linux/bcm27xx/patches-6.6/950-0655-vc4-drm-Remove-the-clear-of-SCALER_DISPBKGND_FILL.patch index 67d8ae27265..fa57c12cf62 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0655-vc4-drm-Remove-the-clear-of-SCALER_DISPBKGND_FILL.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0655-vc4-drm-Remove-the-clear-of-SCALER_DISPBKGND_FILL.patch @@ -25,7 +25,7 @@ Signed-off-by: Dom Cobley --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c -@@ -1349,27 +1349,25 @@ void vc4_hvs_atomic_flush(struct drm_crt +@@ -1304,27 +1304,25 @@ void vc4_hvs_atomic_flush(struct drm_crt WARN_ON(!vc4_state->mm); WARN_ON_ONCE(dlist_next - dlist_start != vc4_state->mm->mm_node.size); diff --git a/target/linux/bcm27xx/patches-6.6/950-0675-drm-vc4-Correct-address-offset-for-planes-with-src_-.patch b/target/linux/bcm27xx/patches-6.6/950-0675-drm-vc4-Correct-address-offset-for-planes-with-src_-.patch index 9eb1ddad939..30c6271bc6f 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0675-drm-vc4-Correct-address-offset-for-planes-with-src_-.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0675-drm-vc4-Correct-address-offset-for-planes-with-src_-.patch @@ -22,7 +22,7 @@ Signed-off-by: Dave Stevenson --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c -@@ -1447,9 +1447,9 @@ static int vc4_plane_mode_set(struct drm +@@ -1473,9 +1473,9 @@ static int vc4_plane_mode_set(struct drm vc4_state->ptr0_offset[0] = vc4_state->dlist_count; for (i = 0; i < num_planes; i++) { @@ -34,7 +34,7 @@ Signed-off-by: Dave Stevenson } /* Pointer Context Word 0/1/2: Written by the HVS */ -@@ -1842,9 +1842,8 @@ static int vc6_plane_mode_set(struct drm +@@ -1868,9 +1868,8 @@ static int vc6_plane_mode_set(struct drm * TODO: This only covers Raster Scan Order planes */ for (i = 0; i < num_planes; i++) { diff --git a/target/linux/bcm27xx/patches-6.6/950-0711-drm-vc4-Add-hvs_dlist_allocs-debugfs-function.patch b/target/linux/bcm27xx/patches-6.6/950-0711-drm-vc4-Add-hvs_dlist_allocs-debugfs-function.patch index c04a5bb0e6d..e8e93d5e80a 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0711-drm-vc4-Add-hvs_dlist_allocs-debugfs-function.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0711-drm-vc4-Add-hvs_dlist_allocs-debugfs-function.patch @@ -50,7 +50,7 @@ Signed-off-by: Dave Stevenson /* The filter kernel is composed of dwords each containing 3 9-bit * signed integers packed next to each other. */ -@@ -1596,6 +1626,8 @@ int vc4_hvs_debugfs_init(struct drm_mino +@@ -1551,6 +1581,8 @@ int vc4_hvs_debugfs_init(struct drm_mino drm_debugfs_add_file(drm, "hvs_underrun", vc4_hvs_debugfs_underrun, NULL); diff --git a/target/linux/bcm27xx/patches-6.6/950-0738-drm-vc4-Drop-planes-that-are-completely-off-screen.patch b/target/linux/bcm27xx/patches-6.6/950-0738-drm-vc4-Drop-planes-that-are-completely-off-screen.patch index 321be130dc5..b8aa8dccfd5 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0738-drm-vc4-Drop-planes-that-are-completely-off-screen.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0738-drm-vc4-Drop-planes-that-are-completely-off-screen.patch @@ -25,7 +25,7 @@ Signed-off-by: Dave Stevenson --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c -@@ -1108,6 +1108,12 @@ static int vc4_plane_mode_set(struct drm +@@ -1134,6 +1134,12 @@ static int vc4_plane_mode_set(struct drm width = vc4_state->src_w[0] >> 16; height = vc4_state->src_h[0] >> 16; @@ -38,7 +38,7 @@ Signed-off-by: Dave Stevenson /* SCL1 is used for Cb/Cr scaling of planar formats. For RGB * and 4:4:4, scl1 should be set to scl0 so both channels of * the scaler do the same thing. For YUV, the Y plane needs -@@ -1623,6 +1629,12 @@ static int vc6_plane_mode_set(struct drm +@@ -1649,6 +1655,12 @@ static int vc6_plane_mode_set(struct drm width = vc4_state->src_w[0] >> 16; height = vc4_state->src_h[0] >> 16; @@ -51,7 +51,7 @@ Signed-off-by: Dave Stevenson /* SCL1 is used for Cb/Cr scaling of planar formats. For RGB * and 4:4:4, scl1 should be set to scl0 so both channels of * the scaler do the same thing. For YUV, the Y plane needs -@@ -1994,6 +2006,9 @@ int vc4_plane_atomic_check(struct drm_pl +@@ -2020,6 +2032,9 @@ int vc4_plane_atomic_check(struct drm_pl if (ret) return ret; diff --git a/target/linux/bcm27xx/patches-6.6/950-0740-drm-vc4-Free-the-dlist-alloc-immediately-if-it-never.patch b/target/linux/bcm27xx/patches-6.6/950-0740-drm-vc4-Free-the-dlist-alloc-immediately-if-it-never.patch index 3782d53e346..dced86878d1 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0740-drm-vc4-Free-the-dlist-alloc-immediately-if-it-never.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0740-drm-vc4-Free-the-dlist-alloc-immediately-if-it-never.patch @@ -23,7 +23,7 @@ Signed-off-by: Dave Stevenson --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h -@@ -667,6 +667,7 @@ struct vc4_hvs_dlist_allocation { +@@ -665,6 +665,7 @@ struct vc4_hvs_dlist_allocation { struct drm_mm_node mm_node; unsigned int channel; u8 target_frame_count; @@ -46,7 +46,7 @@ Signed-off-by: Dave Stevenson spin_lock_irqsave(&hvs->mm_lock, flags); vc4_hvs_free_dlist_entry_locked(hvs, alloc); spin_unlock_irqrestore(&hvs->mm_lock, flags); -@@ -1201,6 +1204,7 @@ static void vc4_hvs_install_dlist(struct +@@ -1195,6 +1198,7 @@ static void vc4_hvs_install_dlist(struct return; WARN_ON(!vc4_state->mm); diff --git a/target/linux/bcm27xx/patches-6.6/950-0763-drm-vc4-Mop-and-moplet-have-different-register-offse.patch b/target/linux/bcm27xx/patches-6.6/950-0763-drm-vc4-Mop-and-moplet-have-different-register-offse.patch index ccf84b313c9..2340240218e 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0763-drm-vc4-Mop-and-moplet-have-different-register-offse.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0763-drm-vc4-Mop-and-moplet-have-different-register-offse.patch @@ -17,7 +17,7 @@ Signed-off-by: Dave Stevenson --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h -@@ -549,6 +549,7 @@ struct vc4_crtc_data { +@@ -550,6 +550,7 @@ struct vc4_crtc_data { struct vc4_txp_data { struct vc4_crtc_data base; enum vc4_encoder_type encoder_type; diff --git a/target/linux/bcm27xx/patches-6.6/950-0829-vc4-hvs-Add-support-for-D0-register-changes.patch b/target/linux/bcm27xx/patches-6.6/950-0829-vc4-hvs-Add-support-for-D0-register-changes.patch index 1bc75773b79..3d13a6a09c3 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0829-vc4-hvs-Add-support-for-D0-register-changes.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0829-vc4-hvs-Add-support-for-D0-register-changes.patch @@ -54,7 +54,7 @@ Signed-off-by: Dom Cobley unsigned int irq; -@@ -714,6 +715,12 @@ struct vc4_crtc_state { +@@ -712,6 +713,12 @@ struct vc4_crtc_state { writel(val, hvs->regs + (offset)); \ } while (0) @@ -244,7 +244,7 @@ Signed-off-by: Dom Cobley out: drm_dev_exit(idx); -@@ -1227,8 +1286,8 @@ static void vc4_hvs_install_dlist(struct +@@ -1221,8 +1280,8 @@ static void vc4_hvs_install_dlist(struct if (vc4->gen >= VC4_GEN_6) HVS_WRITE(SCALER6_DISPX_LPTRS(vc4_state->assigned_channel), @@ -255,7 +255,7 @@ Signed-off-by: Dom Cobley else HVS_WRITE(SCALER_DISPLISTX(vc4_state->assigned_channel), vc4_state->mm->mm_node.start); -@@ -1427,11 +1486,11 @@ void vc4_hvs_atomic_flush(struct drm_crt +@@ -1382,11 +1441,11 @@ void vc4_hvs_atomic_flush(struct drm_crt if (enable_bg_fill) HVS_WRITE(SCALER6_DISPX_CTRL1(channel), HVS_READ(SCALER6_DISPX_CTRL1(channel)) | @@ -269,7 +269,7 @@ Signed-off-by: Dom Cobley } else { /* we can actually run with a lower core clock when background * fill is enabled on VC4_GEN_5 so leave it enabled always. -@@ -1701,7 +1760,7 @@ struct vc4_hvs *__vc4_hvs_alloc(struct v +@@ -1656,7 +1715,7 @@ struct vc4_hvs *__vc4_hvs_alloc(struct v * access a register. Use a plausible size then. */ if (!kunit_get_current_test()) @@ -278,7 +278,7 @@ Signed-off-by: Dom Cobley else dlist_size = 4096; -@@ -1935,14 +1994,17 @@ static int vc6_hvs_hw_init(struct vc4_hv +@@ -1890,14 +1949,17 @@ static int vc6_hvs_hw_init(struct vc4_hv const struct vc6_csc_coeff_entry *coeffs; unsigned int i; @@ -300,7 +300,7 @@ Signed-off-by: Dom Cobley for (i = 0; i < 6; i++) { coeffs = &csc_coeffs[i / 3][i % 3]; -@@ -2041,21 +2103,21 @@ static int vc4_hvs_cob_init(struct vc4_h +@@ -1996,21 +2058,21 @@ static int vc4_hvs_cob_init(struct vc4_h reg = 0; top = 3840; @@ -325,7 +325,7 @@ Signed-off-by: Dom Cobley VC4_SET_FIELD(top, SCALER6_DISPX_COB_TOP) | VC4_SET_FIELD(base, SCALER6_DISPX_COB_BASE)); break; -@@ -2086,7 +2148,10 @@ static int vc4_hvs_bind(struct device *d +@@ -2041,7 +2103,10 @@ static int vc4_hvs_bind(struct device *d hvs->regset.base = hvs->regs; @@ -337,7 +337,7 @@ Signed-off-by: Dom Cobley hvs->regset.regs = vc6_hvs_regs; hvs->regset.nregs = ARRAY_SIZE(vc6_hvs_regs); } else { -@@ -2253,6 +2318,7 @@ static void vc4_hvs_dev_remove(struct pl +@@ -2208,6 +2273,7 @@ static void vc4_hvs_dev_remove(struct pl static const struct of_device_id vc4_hvs_dt_match[] = { { .compatible = "brcm,bcm2711-hvs" }, { .compatible = "brcm,bcm2712-hvs" }, diff --git a/target/linux/bcm27xx/patches-6.6/950-0830-vc4-hvs-Updates-to-support-D0-alpha-and-csc-changes.patch b/target/linux/bcm27xx/patches-6.6/950-0830-vc4-hvs-Updates-to-support-D0-alpha-and-csc-changes.patch index 0a38601048f..d88e6a744cd 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0830-vc4-hvs-Updates-to-support-D0-alpha-and-csc-changes.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0830-vc4-hvs-Updates-to-support-D0-alpha-and-csc-changes.patch @@ -16,7 +16,7 @@ Signed-off-by: Dom Cobley --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c -@@ -1933,6 +1933,17 @@ static int vc4_hvs_hw_init(struct vc4_hv +@@ -1888,6 +1888,17 @@ static int vc4_hvs_hw_init(struct vc4_hv #define CFC1_N_MA_CSC_COEFF_C23(x) (0xa03c + ((x) * 0x3000)) #define CFC1_N_MA_CSC_COEFF_C24(x) (0xa040 + ((x) * 0x3000)) @@ -34,7 +34,7 @@ Signed-off-by: Dom Cobley /* 4 S2.22 multiplication factors, and 1 S9.15 addititive element for each of 3 * output components */ -@@ -2003,31 +2014,43 @@ static int vc6_hvs_hw_init(struct vc4_hv +@@ -1958,31 +1969,43 @@ static int vc6_hvs_hw_init(struct vc4_hv HVS_WRITE(SCALER6(PRI_MAP0), 0xffffffff); HVS_WRITE(SCALER6(PRI_MAP1), 0xffffffff); @@ -104,7 +104,7 @@ Signed-off-by: Dom Cobley return 0; --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c -@@ -1054,6 +1054,12 @@ static u32 vc4_hvs5_get_alpha_blend_mode +@@ -1080,6 +1080,12 @@ static u32 vc4_hvs5_get_alpha_blend_mode WARN_ON_ONCE(vc4->gen != VC4_GEN_5 && vc4->gen != VC4_GEN_6); @@ -117,7 +117,7 @@ Signed-off-by: Dom Cobley if (!state->fb->format->has_alpha) return VC4_SET_FIELD(SCALER5_CTL2_ALPHA_MODE_FIXED, SCALER5_CTL2_ALPHA_MODE); -@@ -1569,14 +1575,13 @@ static int vc4_plane_mode_set(struct drm +@@ -1595,14 +1601,13 @@ static int vc4_plane_mode_set(struct drm static u32 vc6_plane_get_csc_mode(struct vc4_plane_state *vc4_state) { struct drm_plane_state *state = &vc4_state->base; @@ -133,7 +133,7 @@ Signed-off-by: Dom Cobley /* CSC pre-loaded with: * 0 = BT601 limited range * 1 = BT709 limited range -@@ -1590,8 +1595,15 @@ static u32 vc6_plane_get_csc_mode(struct +@@ -1616,8 +1621,15 @@ static u32 vc6_plane_get_csc_mode(struct if (color_range > DRM_COLOR_YCBCR_FULL_RANGE) color_range = DRM_COLOR_YCBCR_LIMITED_RANGE; diff --git a/target/linux/bcm27xx/patches-6.6/950-0833-drm-vc4-Add-2712-support-to-vc4_plane_async_set_fb.patch b/target/linux/bcm27xx/patches-6.6/950-0833-drm-vc4-Add-2712-support-to-vc4_plane_async_set_fb.patch index 46a66f4c59d..423e5b63c94 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0833-drm-vc4-Add-2712-support-to-vc4_plane_async_set_fb.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0833-drm-vc4-Add-2712-support-to-vc4_plane_async_set_fb.patch @@ -17,7 +17,7 @@ Signed-off-by: Dave Stevenson --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c -@@ -1877,7 +1877,7 @@ static int vc6_plane_mode_set(struct drm +@@ -1903,7 +1903,7 @@ static int vc6_plane_mode_set(struct drm * The UPM buffer will be allocated in * vc6_plane_allocate_upm(). */ @@ -26,7 +26,7 @@ Signed-off-by: Dave Stevenson SCALER6_PTR0_UPPER_ADDR)); /* Pointer Word 1 */ -@@ -2079,7 +2079,8 @@ void vc4_plane_async_set_fb(struct drm_p +@@ -2105,7 +2105,8 @@ void vc4_plane_async_set_fb(struct drm_p { struct vc4_plane_state *vc4_state = to_vc4_plane_state(plane->state); struct drm_gem_dma_object *bo = drm_fb_dma_get_gem_obj(fb, 0); @@ -36,7 +36,7 @@ Signed-off-by: Dave Stevenson int idx; if (!drm_dev_enter(plane->dev, &idx)) -@@ -2089,19 +2090,38 @@ void vc4_plane_async_set_fb(struct drm_p +@@ -2115,19 +2116,38 @@ void vc4_plane_async_set_fb(struct drm_p * because this is only called on the primary plane. */ WARN_ON_ONCE(plane->state->crtc_x < 0 || plane->state->crtc_y < 0); diff --git a/target/linux/bcm27xx/patches-6.6/950-0834-drm-vc4-Fix-atomic_async_check-to-call-the-right-mod.patch b/target/linux/bcm27xx/patches-6.6/950-0834-drm-vc4-Fix-atomic_async_check-to-call-the-right-mod.patch index 07a36b16928..49d2129c841 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0834-drm-vc4-Fix-atomic_async_check-to-call-the-right-mod.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0834-drm-vc4-Fix-atomic_async_check-to-call-the-right-mod.patch @@ -19,7 +19,7 @@ Signed-off-by: Dave Stevenson --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c -@@ -2205,11 +2205,15 @@ static int vc4_plane_atomic_async_check( +@@ -2231,11 +2231,15 @@ static int vc4_plane_atomic_async_check( { struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane); diff --git a/target/linux/bcm27xx/patches-6.6/950-0884-drm-vc4-Drop-planes-that-have-0-destination-size.patch b/target/linux/bcm27xx/patches-6.6/950-0884-drm-vc4-Drop-planes-that-have-0-destination-size.patch index 3e4bed22d4a..3796a923a8e 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0884-drm-vc4-Drop-planes-that-have-0-destination-size.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0884-drm-vc4-Drop-planes-that-have-0-destination-size.patch @@ -16,7 +16,7 @@ Signed-off-by: Dave Stevenson --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c -@@ -1114,7 +1114,7 @@ static int vc4_plane_mode_set(struct drm +@@ -1140,7 +1140,7 @@ static int vc4_plane_mode_set(struct drm width = vc4_state->src_w[0] >> 16; height = vc4_state->src_h[0] >> 16; @@ -25,7 +25,7 @@ Signed-off-by: Dave Stevenson /* 0 source size probably means the plane is offscreen */ vc4_state->dlist_initialized = 1; return 0; -@@ -1641,8 +1641,10 @@ static int vc6_plane_mode_set(struct drm +@@ -1667,8 +1667,10 @@ static int vc6_plane_mode_set(struct drm width = vc4_state->src_w[0] >> 16; height = vc4_state->src_h[0] >> 16; @@ -38,7 +38,7 @@ Signed-off-by: Dave Stevenson vc4_state->dlist_initialized = 1; return 0; } -@@ -2018,7 +2020,8 @@ int vc4_plane_atomic_check(struct drm_pl +@@ -2044,7 +2046,8 @@ int vc4_plane_atomic_check(struct drm_pl if (ret) return ret; diff --git a/target/linux/bcm27xx/patches-6.6/950-0885-vc4-hvs-Support-fixed-alpha-correctly-on-2712D0.patch b/target/linux/bcm27xx/patches-6.6/950-0885-vc4-hvs-Support-fixed-alpha-correctly-on-2712D0.patch index 0100b20df53..3147ac297f2 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0885-vc4-hvs-Support-fixed-alpha-correctly-on-2712D0.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0885-vc4-hvs-Support-fixed-alpha-correctly-on-2712D0.patch @@ -16,7 +16,7 @@ Signed-off-by: Dom Cobley --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c -@@ -1079,6 +1079,21 @@ static u32 vc4_hvs5_get_alpha_blend_mode +@@ -1105,6 +1105,21 @@ static u32 vc4_hvs5_get_alpha_blend_mode } } @@ -38,7 +38,7 @@ Signed-off-by: Dom Cobley /* Writes out a full display list for an active plane to the plane's * private dlist state. */ -@@ -1824,7 +1839,7 @@ static int vc6_plane_mode_set(struct drm +@@ -1850,7 +1865,7 @@ static int vc6_plane_mode_set(struct drm vc4_dlist_write(vc4_state, SCALER6_CTL0_VALID | VC4_SET_FIELD(tiling, SCALER6_CTL0_ADDR_MODE) | diff --git a/target/linux/bcm27xx/patches-6.6/950-0902-vc4-hvs-Fix-lbm-size-calculation-for-yuv.patch b/target/linux/bcm27xx/patches-6.6/950-0902-vc4-hvs-Fix-lbm-size-calculation-for-yuv.patch index 12f762ac91f..80724fd6ef1 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0902-vc4-hvs-Fix-lbm-size-calculation-for-yuv.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0902-vc4-hvs-Fix-lbm-size-calculation-for-yuv.patch @@ -18,7 +18,7 @@ Signed-off-by: Dom Cobley --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c -@@ -733,7 +733,7 @@ static unsigned int vc4_lbm_channel_size +@@ -742,7 +742,7 @@ static unsigned int vc4_lbm_channel_size if (!components) return 0; diff --git a/target/linux/bcm27xx/patches-6.6/950-0989-drm-vc4-Enable-bg_fill-if-there-are-no-planes-enable.patch b/target/linux/bcm27xx/patches-6.6/950-0989-drm-vc4-Enable-bg_fill-if-there-are-no-planes-enable.patch index addbb3691f0..10d7f571194 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0989-drm-vc4-Enable-bg_fill-if-there-are-no-planes-enable.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0989-drm-vc4-Enable-bg_fill-if-there-are-no-planes-enable.patch @@ -19,12 +19,12 @@ Signed-off-by: Dave Stevenson --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c -@@ -1406,7 +1406,7 @@ void vc4_hvs_atomic_flush(struct drm_crt +@@ -1400,7 +1400,7 @@ void vc4_hvs_atomic_flush(struct drm_crt struct drm_plane *plane; struct vc4_plane_state *vc4_plane_state; bool debug_dump_regs = false; - bool enable_bg_fill = false; + bool enable_bg_fill = true; u32 __iomem *dlist_start, *dlist_next; - unsigned long irqflags; unsigned int zpos = 0; + bool found = false; diff --git a/target/linux/bcm27xx/patches-6.6/950-1065-drm-vc4-Add-option-to-call-from-crtc-to-encoder-on-v.patch b/target/linux/bcm27xx/patches-6.6/950-1065-drm-vc4-Add-option-to-call-from-crtc-to-encoder-on-v.patch index 8137b10592d..d806631555f 100644 --- a/target/linux/bcm27xx/patches-6.6/950-1065-drm-vc4-Add-option-to-call-from-crtc-to-encoder-on-v.patch +++ b/target/linux/bcm27xx/patches-6.6/950-1065-drm-vc4-Add-option-to-call-from-crtc-to-encoder-on-v.patch @@ -50,7 +50,7 @@ Signed-off-by: Dave Stevenson } --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h -@@ -503,6 +503,7 @@ struct vc4_encoder { +@@ -504,6 +504,7 @@ struct vc4_encoder { void (*post_crtc_disable)(struct drm_encoder *encoder, struct drm_atomic_state *state); void (*post_crtc_powerdown)(struct drm_encoder *encoder, struct drm_atomic_state *state); diff --git a/target/linux/bcm27xx/patches-6.6/950-1115-mmc-sd-halt-CQHCI-before-issuing-a-cache-flush-comma.patch b/target/linux/bcm27xx/patches-6.6/950-1115-mmc-sd-halt-CQHCI-before-issuing-a-cache-flush-comma.patch deleted file mode 100644 index 3f01a7ba09c..00000000000 --- a/target/linux/bcm27xx/patches-6.6/950-1115-mmc-sd-halt-CQHCI-before-issuing-a-cache-flush-comma.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 8e40644b272a4ddc9d3b58b4373dffcef02d1b63 Mon Sep 17 00:00:00 2001 -From: Jonathan Bell -Date: Tue, 4 Jun 2024 13:21:47 +0100 -Subject: [PATCH 1115/1135] mmc: sd: halt CQHCI before issuing a cache flush - command - -SD cards perform cache flushes by a CMD49 extension register write - -which needs to be started from the SDHCI command/argument registers and -not a CQHCI slot. - -Host access to SD/CQ registers should be exclusive to one or the other, -so issue a halt before doing the command. - -Signed-off-by: Jonathan Bell ---- - drivers/mmc/core/sd.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - ---- a/drivers/mmc/core/sd.c -+++ b/drivers/mmc/core/sd.c -@@ -1265,6 +1265,14 @@ static int sd_flush_cache(struct mmc_hos - reg_buf = card->ext_reg_buf; - - /* -+ * Flushing requires sending CMD49 (adtc), which can't be done as a DCMD -+ * and conflicts with CQHCI - temporarily turn CQE off to use the SDHCI -+ * command/argument registers. -+ */ -+ if (host->cqe_on) -+ host->cqe_ops->cqe_off(host); -+ -+ /* - * Set Flush Cache at bit 0 in the performance enhancement register at - * 261 bytes offset. - */ diff --git a/target/linux/bcm27xx/patches-6.6/950-1168-fixup-mmc-restrict-posted-write-counts-for-SD-cards-.patch b/target/linux/bcm27xx/patches-6.6/950-1168-fixup-mmc-restrict-posted-write-counts-for-SD-cards-.patch index 4f1d02c74da..b4f30b4b3c4 100644 --- a/target/linux/bcm27xx/patches-6.6/950-1168-fixup-mmc-restrict-posted-write-counts-for-SD-cards-.patch +++ b/target/linux/bcm27xx/patches-6.6/950-1168-fixup-mmc-restrict-posted-write-counts-for-SD-cards-.patch @@ -60,7 +60,7 @@ Signed-off-by: Jonathan Bell } card->ext_perf.fno = fno; -@@ -1383,6 +1384,7 @@ retry: +@@ -1375,6 +1376,7 @@ retry: card->ocr = ocr; card->type = MMC_TYPE_SD; diff --git a/target/linux/bcm27xx/patches-6.6/950-1199-drm-vc4-Disable-the-2pixel-clock-odd-timings-workaro.patch b/target/linux/bcm27xx/patches-6.6/950-1199-drm-vc4-Disable-the-2pixel-clock-odd-timings-workaro.patch index 78806c2b155..ea64afd5f9f 100644 --- a/target/linux/bcm27xx/patches-6.6/950-1199-drm-vc4-Disable-the-2pixel-clock-odd-timings-workaro.patch +++ b/target/linux/bcm27xx/patches-6.6/950-1199-drm-vc4-Disable-the-2pixel-clock-odd-timings-workaro.patch @@ -135,7 +135,7 @@ Signed-off-by: Dave Stevenson }, --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h -@@ -569,6 +569,8 @@ struct vc4_pv_data { +@@ -570,6 +570,8 @@ struct vc4_pv_data { /* Number of pixels output per clock period */ u8 pixels_per_clock; diff --git a/target/linux/bcm27xx/patches-6.6/950-1218-Bluetooth-hci_sync-Fix-crash-on-NULL-parent.patch b/target/linux/bcm27xx/patches-6.6/950-1218-Bluetooth-hci_sync-Fix-crash-on-NULL-parent.patch new file mode 100644 index 00000000000..272f711e632 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1218-Bluetooth-hci_sync-Fix-crash-on-NULL-parent.patch @@ -0,0 +1,27 @@ +From ad2babc6596ba4f500454a4eaa607f3b49fcbcbe Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 7 Aug 2024 17:41:31 +0100 +Subject: [PATCH 1218/1350] Bluetooth: hci_sync: Fix crash on NULL parent + +Although later functions can handle a NULL fwnode, fwnode can't handle +being passed a NULL pointer. + +See: https://github.com/raspberrypi/linux/issues/6305 + +Signed-off-by: Phil Elwell +--- + net/bluetooth/hci_sync.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/bluetooth/hci_sync.c ++++ b/net/bluetooth/hci_sync.c +@@ -4861,7 +4861,8 @@ static const struct { + */ + static int hci_dev_setup_sync(struct hci_dev *hdev) + { +- struct fwnode_handle *fwnode = dev_fwnode(hdev->dev.parent); ++ struct fwnode_handle *fwnode = ++ hdev->dev.parent ? dev_fwnode(hdev->dev.parent) : NULL; + int ret = 0; + bool invalid_bdaddr; + size_t i; diff --git a/target/linux/bcm27xx/patches-6.6/950-1219-overlays-add-overlay-for-generic-I2S-clock-master-DA.patch b/target/linux/bcm27xx/patches-6.6/950-1219-overlays-add-overlay-for-generic-I2S-clock-master-DA.patch new file mode 100644 index 00000000000..8fbde277ef7 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1219-overlays-add-overlay-for-generic-I2S-clock-master-DA.patch @@ -0,0 +1,96 @@ +From 209e8a3e6646f25abb352fd5a8a4c2e855b1e952 Mon Sep 17 00:00:00 2001 +From: Adrian Figueroa +Date: Wed, 14 Aug 2024 20:00:12 +0200 +Subject: [PATCH 1219/1350] overlays: add overlay for generic I2S clock-master + DAC + +Adds an overlay for supporting a generic I2S DAC that +acts as the clock master on the bus. +The data format is 32 bit stereo. + +Signed-off-by: Adrian Figueroa +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 6 +++ + .../dts/overlays/i2s-master-dac-overlay.dts | 50 +++++++++++++++++++ + 3 files changed, 57 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/i2s-master-dac-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -125,6 +125,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + i2c6.dtbo \ + i2s-dac.dtbo \ + i2s-gpio28-31.dtbo \ ++ i2s-master-dac.dtbo \ + ilitek251x.dtbo \ + imx219.dtbo \ + imx258.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -2633,6 +2633,12 @@ Load: dtoverlay=i2s-gpio28-31 + Params: + + ++Name: i2s-master-dac ++Info: Configures a generic I2S DAC soundcard that acts as a clock master. ++Load: dtoverlay=i2s-master-dac ++Params: ++ ++ + Name: ilitek251x + Info: Enables I2C connected Ilitek 251x multiple touch controller using + GPIO 4 (pin 7 on GPIO header) for interrupt. +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/i2s-master-dac-overlay.dts +@@ -0,0 +1,50 @@ ++// Definitions for a generic I2S DAC that acts as clock master on the bus. ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835"; ++ ++ fragment@0 { ++ target = <&i2s_clk_consumer>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target-path = "/"; ++ __overlay__ { ++ codec_bare: codec_bare { ++ compatible = "linux,spdif-dit"; ++ #sound-dai-cells = <0>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&sound>; ++ __overlay__ { ++ compatible = "simple-audio-card"; ++ i2s-controller = <&i2s_clk_consumer>; ++ status = "okay"; ++ ++ simple-audio-card,name = "i2s-master-dac"; ++ simple-audio-card,format = "i2s"; ++ ++ simple-audio-card,bitclock-master = <&snd_codec>; ++ simple-audio-card,frame-master = <&snd_codec>; ++ ++ simple-audio-card,cpu { ++ sound-dai = <&i2s_clk_consumer>; ++ dai-tdm-slot-num = <2>; ++ dai-tdm-slot-width = <32>; ++ }; ++ ++ snd_codec: simple-audio-card,codec { ++ sound-dai = <&codec_bare>; ++ }; ++ }; ++ }; ++}; diff --git a/target/linux/bcm27xx/patches-6.6/950-1220-ASoC-DACplusADCPro-put-ADC-control-definitions-in-he.patch b/target/linux/bcm27xx/patches-6.6/950-1220-ASoC-DACplusADCPro-put-ADC-control-definitions-in-he.patch new file mode 100644 index 00000000000..6de452829c0 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1220-ASoC-DACplusADCPro-put-ADC-control-definitions-in-he.patch @@ -0,0 +1,275 @@ +From 15ca476264094b25d0a210109a061192a468117b Mon Sep 17 00:00:00 2001 +From: j-schambacher +Date: Thu, 15 Aug 2024 16:08:14 +0200 +Subject: [PATCH 1220/1350] ASoC: DACplusADCPro - put ADC control definitions + in header file + +For easier maintenance all ADC ALSA-Kcontrols and the respective +definitions are placed into a new header file that is included +by the existing DAC+ADC Pro driver and a new, soon to be +released ADC only board driver using the same controls. + +Signed-off-by: j-schambacher +--- + sound/soc/bcm/hifiberry_adc_controls.h | 128 ++++++++++++++++++++++++ + sound/soc/bcm/hifiberry_dacplusadcpro.c | 110 +------------------- + 2 files changed, 129 insertions(+), 109 deletions(-) + create mode 100644 sound/soc/bcm/hifiberry_adc_controls.h + +--- /dev/null ++++ b/sound/soc/bcm/hifiberry_adc_controls.h +@@ -0,0 +1,128 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * ALSA mixer/Kcontrol definitions common to HiFiBerry ADCs ++ * ++ * used by DAC+ADC Pro (hifiberry_dacplusadcpro.c), ++ * ADC (hifiberry_adc.c) ++ * ++ * Author: Joerg Schambacher ++ * Copyright 2024 ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 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. ++ */ ++ ++static const unsigned int pcm186x_adc_input_channel_sel_value[] = { ++ 0x00, 0x01, 0x02, 0x03, 0x10 ++}; ++ ++static const char * const pcm186x_adcl_input_channel_sel_text[] = { ++ "No Select", ++ "VINL1[SE]", /* Default for ADCL */ ++ "VINL2[SE]", ++ "VINL2[SE] + VINL1[SE]", ++ "{VIN1P, VIN1M}[DIFF]" ++}; ++ ++static const char * const pcm186x_adcr_input_channel_sel_text[] = { ++ "No Select", ++ "VINR1[SE]", /* Default for ADCR */ ++ "VINR2[SE]", ++ "VINR2[SE] + VINR1[SE]", ++ "{VIN2P, VIN2M}[DIFF]" ++}; ++ ++static const struct soc_enum pcm186x_adc_input_channel_sel[] = { ++ SOC_VALUE_ENUM_SINGLE(PCM186X_ADC1_INPUT_SEL_L, 0, ++ PCM186X_ADC_INPUT_SEL_MASK, ++ ARRAY_SIZE(pcm186x_adcl_input_channel_sel_text), ++ pcm186x_adcl_input_channel_sel_text, ++ pcm186x_adc_input_channel_sel_value), ++ SOC_VALUE_ENUM_SINGLE(PCM186X_ADC1_INPUT_SEL_R, 0, ++ PCM186X_ADC_INPUT_SEL_MASK, ++ ARRAY_SIZE(pcm186x_adcr_input_channel_sel_text), ++ pcm186x_adcr_input_channel_sel_text, ++ pcm186x_adc_input_channel_sel_value), ++}; ++ ++static const unsigned int pcm186x_mic_bias_sel_value[] = { ++ 0x00, 0x01, 0x11 ++}; ++ ++static const char * const pcm186x_mic_bias_sel_text[] = { ++ "Mic Bias off", ++ "Mic Bias on", ++ "Mic Bias with Bypass Resistor" ++}; ++ ++static const struct soc_enum pcm186x_mic_bias_sel[] = { ++ SOC_VALUE_ENUM_SINGLE(PCM186X_MIC_BIAS_CTRL, 0, ++ GENMASK(4, 0), ++ ARRAY_SIZE(pcm186x_mic_bias_sel_text), ++ pcm186x_mic_bias_sel_text, ++ pcm186x_mic_bias_sel_value), ++}; ++ ++static const unsigned int pcm186x_gain_sel_value[] = { ++ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, ++ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, ++ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, ++ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, ++ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, ++ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, ++ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, ++ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, ++ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, ++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, ++ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, ++ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, ++ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, ++ 0x50 ++}; ++ ++static const char * const pcm186x_gain_sel_text[] = { ++ "-12.0dB", "-11.5dB", "-11.0dB", "-10.5dB", "-10.0dB", "-9.5dB", ++ "-9.0dB", "-8.5dB", "-8.0dB", "-7.5dB", "-7.0dB", "-6.5dB", ++ "-6.0dB", "-5.5dB", "-5.0dB", "-4.5dB", "-4.0dB", "-3.5dB", ++ "-3.0dB", "-2.5dB", "-2.0dB", "-1.5dB", "-1.0dB", "-0.5dB", ++ "0.0dB", "0.5dB", "1.0dB", "1.5dB", "2.0dB", "2.5dB", ++ "3.0dB", "3.5dB", "4.0dB", "4.5dB", "5.0dB", "5.5dB", ++ "6.0dB", "6.5dB", "7.0dB", "7.5dB", "8.0dB", "8.5dB", ++ "9.0dB", "9.5dB", "10.0dB", "10.5dB", "11.0dB", "11.5dB", ++ "12.0dB", "12.5dB", "13.0dB", "13.5dB", "14.0dB", "14.5dB", ++ "15.0dB", "15.5dB", "16.0dB", "16.5dB", "17.0dB", "17.5dB", ++ "18.0dB", "18.5dB", "19.0dB", "19.5dB", "20.0dB", "20.5dB", ++ "21.0dB", "21.5dB", "22.0dB", "22.5dB", "23.0dB", "23.5dB", ++ "24.0dB", "24.5dB", "25.0dB", "25.5dB", "26.0dB", "26.5dB", ++ "27.0dB", "27.5dB", "28.0dB", "28.5dB", "29.0dB", "29.5dB", ++ "30.0dB", "30.5dB", "31.0dB", "31.5dB", "32.0dB", "32.5dB", ++ "33.0dB", "33.5dB", "34.0dB", "34.5dB", "35.0dB", "35.5dB", ++ "36.0dB", "36.5dB", "37.0dB", "37.5dB", "38.0dB", "38.5dB", ++ "39.0dB", "39.5dB", "40.0dB"}; ++ ++static const struct soc_enum pcm186x_gain_sel[] = { ++ SOC_VALUE_ENUM_SINGLE(PCM186X_PGA_VAL_CH1_L, 0, ++ 0xff, ++ ARRAY_SIZE(pcm186x_gain_sel_text), ++ pcm186x_gain_sel_text, ++ pcm186x_gain_sel_value), ++ SOC_VALUE_ENUM_SINGLE(PCM186X_PGA_VAL_CH1_R, 0, ++ 0xff, ++ ARRAY_SIZE(pcm186x_gain_sel_text), ++ pcm186x_gain_sel_text, ++ pcm186x_gain_sel_value), ++}; ++ ++static const struct snd_kcontrol_new pcm1863_snd_controls_card[] = { ++ SOC_ENUM("ADC Left Input", pcm186x_adc_input_channel_sel[0]), ++ SOC_ENUM("ADC Right Input", pcm186x_adc_input_channel_sel[1]), ++ SOC_ENUM("ADC Mic Bias", pcm186x_mic_bias_sel), ++ SOC_ENUM("PGA Gain Left", pcm186x_gain_sel[0]), ++ SOC_ENUM("PGA Gain Right", pcm186x_gain_sel[1]), ++}; +--- a/sound/soc/bcm/hifiberry_dacplusadcpro.c ++++ b/sound/soc/bcm/hifiberry_dacplusadcpro.c +@@ -37,6 +37,7 @@ + + #include "../codecs/pcm512x.h" + #include "../codecs/pcm186x.h" ++#include "hifiberry_adc_controls.h" + + #define HIFIBERRY_DACPRO_NOCLOCK 0 + #define HIFIBERRY_DACPRO_CLK44EN 1 +@@ -57,115 +58,6 @@ static bool snd_rpi_hifiberry_is_dacpro; + static bool digital_gain_0db_limit = true; + static bool leds_off; + +-static const unsigned int pcm186x_adc_input_channel_sel_value[] = { +- 0x00, 0x01, 0x02, 0x03, 0x10 +-}; +- +-static const char * const pcm186x_adcl_input_channel_sel_text[] = { +- "No Select", +- "VINL1[SE]", /* Default for ADCL */ +- "VINL2[SE]", +- "VINL2[SE] + VINL1[SE]", +- "{VIN1P, VIN1M}[DIFF]" +-}; +- +-static const char * const pcm186x_adcr_input_channel_sel_text[] = { +- "No Select", +- "VINR1[SE]", /* Default for ADCR */ +- "VINR2[SE]", +- "VINR2[SE] + VINR1[SE]", +- "{VIN2P, VIN2M}[DIFF]" +-}; +- +-static const struct soc_enum pcm186x_adc_input_channel_sel[] = { +- SOC_VALUE_ENUM_SINGLE(PCM186X_ADC1_INPUT_SEL_L, 0, +- PCM186X_ADC_INPUT_SEL_MASK, +- ARRAY_SIZE(pcm186x_adcl_input_channel_sel_text), +- pcm186x_adcl_input_channel_sel_text, +- pcm186x_adc_input_channel_sel_value), +- SOC_VALUE_ENUM_SINGLE(PCM186X_ADC1_INPUT_SEL_R, 0, +- PCM186X_ADC_INPUT_SEL_MASK, +- ARRAY_SIZE(pcm186x_adcr_input_channel_sel_text), +- pcm186x_adcr_input_channel_sel_text, +- pcm186x_adc_input_channel_sel_value), +-}; +- +-static const unsigned int pcm186x_mic_bias_sel_value[] = { +- 0x00, 0x01, 0x11 +-}; +- +-static const char * const pcm186x_mic_bias_sel_text[] = { +- "Mic Bias off", +- "Mic Bias on", +- "Mic Bias with Bypass Resistor" +-}; +- +-static const struct soc_enum pcm186x_mic_bias_sel[] = { +- SOC_VALUE_ENUM_SINGLE(PCM186X_MIC_BIAS_CTRL, 0, +- GENMASK(4, 0), +- ARRAY_SIZE(pcm186x_mic_bias_sel_text), +- pcm186x_mic_bias_sel_text, +- pcm186x_mic_bias_sel_value), +-}; +- +-static const unsigned int pcm186x_gain_sel_value[] = { +- 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, +- 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, +- 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, +- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, +- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, +- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, +- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, +- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, +- 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, +- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, +- 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, +- 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, +- 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, +- 0x50 +-}; +- +-static const char * const pcm186x_gain_sel_text[] = { +- "-12.0dB", "-11.5dB", "-11.0dB", "-10.5dB", "-10.0dB", "-9.5dB", +- "-9.0dB", "-8.5dB", "-8.0dB", "-7.5dB", "-7.0dB", "-6.5dB", +- "-6.0dB", "-5.5dB", "-5.0dB", "-4.5dB", "-4.0dB", "-3.5dB", +- "-3.0dB", "-2.5dB", "-2.0dB", "-1.5dB", "-1.0dB", "-0.5dB", +- "0.0dB", "0.5dB", "1.0dB", "1.5dB", "2.0dB", "2.5dB", +- "3.0dB", "3.5dB", "4.0dB", "4.5dB", "5.0dB", "5.5dB", +- "6.0dB", "6.5dB", "7.0dB", "7.5dB", "8.0dB", "8.5dB", +- "9.0dB", "9.5dB", "10.0dB", "10.5dB", "11.0dB", "11.5dB", +- "12.0dB", "12.5dB", "13.0dB", "13.5dB", "14.0dB", "14.5dB", +- "15.0dB", "15.5dB", "16.0dB", "16.5dB", "17.0dB", "17.5dB", +- "18.0dB", "18.5dB", "19.0dB", "19.5dB", "20.0dB", "20.5dB", +- "21.0dB", "21.5dB", "22.0dB", "22.5dB", "23.0dB", "23.5dB", +- "24.0dB", "24.5dB", "25.0dB", "25.5dB", "26.0dB", "26.5dB", +- "27.0dB", "27.5dB", "28.0dB", "28.5dB", "29.0dB", "29.5dB", +- "30.0dB", "30.5dB", "31.0dB", "31.5dB", "32.0dB", "32.5dB", +- "33.0dB", "33.5dB", "34.0dB", "34.5dB", "35.0dB", "35.5dB", +- "36.0dB", "36.5dB", "37.0dB", "37.5dB", "38.0dB", "38.5dB", +- "39.0dB", "39.5dB", "40.0dB"}; +- +-static const struct soc_enum pcm186x_gain_sel[] = { +- SOC_VALUE_ENUM_SINGLE(PCM186X_PGA_VAL_CH1_L, 0, +- 0xff, +- ARRAY_SIZE(pcm186x_gain_sel_text), +- pcm186x_gain_sel_text, +- pcm186x_gain_sel_value), +- SOC_VALUE_ENUM_SINGLE(PCM186X_PGA_VAL_CH1_R, 0, +- 0xff, +- ARRAY_SIZE(pcm186x_gain_sel_text), +- pcm186x_gain_sel_text, +- pcm186x_gain_sel_value), +-}; +- +-static const struct snd_kcontrol_new pcm1863_snd_controls_card[] = { +- SOC_ENUM("ADC Left Input", pcm186x_adc_input_channel_sel[0]), +- SOC_ENUM("ADC Right Input", pcm186x_adc_input_channel_sel[1]), +- SOC_ENUM("ADC Mic Bias", pcm186x_mic_bias_sel), +- SOC_ENUM("PGA Gain Left", pcm186x_gain_sel[0]), +- SOC_ENUM("PGA Gain Right", pcm186x_gain_sel[1]), +-}; +- + static int pcm1863_add_controls(struct snd_soc_component *component) + { + snd_soc_add_component_controls(component, diff --git a/target/linux/bcm27xx/patches-6.6/950-1222-drm-rp1-rp1-dsi-Add-DRM_FORMAT_ARGB8888-and-DRM_FORM.patch b/target/linux/bcm27xx/patches-6.6/950-1222-drm-rp1-rp1-dsi-Add-DRM_FORMAT_ARGB8888-and-DRM_FORM.patch new file mode 100644 index 00000000000..3f4be4c1111 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1222-drm-rp1-rp1-dsi-Add-DRM_FORMAT_ARGB8888-and-DRM_FORM.patch @@ -0,0 +1,48 @@ +From 9c5d91f6b938c23065ddc21c8654c5e222c35687 Mon Sep 17 00:00:00 2001 +From: Jan Kehren +Date: Fri, 16 Aug 2024 13:47:50 +0000 +Subject: [PATCH 1222/1350] drm: rp1: rp1-dsi: Add DRM_FORMAT_ARGB8888 and + DRM_FORMAT_ABGR8888 + +Android requires this. +As the underlying hardware doesn't support alpha blending, +we ignore the alpha value. + +Signed-off-by: Jan Kehren +--- + drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi.c | 2 ++ + drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi_dma.c | 12 ++++++++++++ + 2 files changed, 14 insertions(+) + +--- a/drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi.c ++++ b/drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi.c +@@ -229,6 +229,8 @@ static const struct drm_mode_config_func + static const u32 rp1dsi_formats[] = { + DRM_FORMAT_XRGB8888, + DRM_FORMAT_XBGR8888, ++ DRM_FORMAT_ARGB8888, ++ DRM_FORMAT_ABGR8888, + DRM_FORMAT_RGB888, + DRM_FORMAT_BGR888, + DRM_FORMAT_RGB565 +--- a/drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi_dma.c ++++ b/drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi_dma.c +@@ -247,6 +247,18 @@ static const struct rp1dsi_ipixfmt my_fo + .rgbsz = BITS(DPI_DMA_RGBSZ_BPP, 3), + }, + { ++ .format = DRM_FORMAT_ARGB8888, ++ .mask = IMASK_RGB(0x3fc, 0x3fc, 0x3fc), ++ .shift = ISHIFT_RGB(23, 15, 7), ++ .rgbsz = BITS(DPI_DMA_RGBSZ_BPP, 3), ++ }, ++ { ++ .format = DRM_FORMAT_ABGR8888, ++ .mask = IMASK_RGB(0x3fc, 0x3fc, 0x3fc), ++ .shift = ISHIFT_RGB(7, 15, 23), ++ .rgbsz = BITS(DPI_DMA_RGBSZ_BPP, 3), ++ }, ++ { + .format = DRM_FORMAT_RGB888, + .mask = IMASK_RGB(0x3fc, 0x3fc, 0x3fc), + .shift = ISHIFT_RGB(23, 15, 7), diff --git a/target/linux/bcm27xx/patches-6.6/950-1223-drm-rp1-rp1-dpi-Add-DRM_FORMAT_ARGB8888-and-DRM_FORM.patch b/target/linux/bcm27xx/patches-6.6/950-1223-drm-rp1-rp1-dpi-Add-DRM_FORMAT_ARGB8888-and-DRM_FORM.patch new file mode 100644 index 00000000000..a24a0e94207 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1223-drm-rp1-rp1-dpi-Add-DRM_FORMAT_ARGB8888-and-DRM_FORM.patch @@ -0,0 +1,48 @@ +From 9f0523de1b7ef122fae527326372a4ab5aa42fa6 Mon Sep 17 00:00:00 2001 +From: Jan Kehren +Date: Tue, 20 Aug 2024 08:08:50 +0000 +Subject: [PATCH 1223/1350] drm: rp1: rp1-dpi: Add DRM_FORMAT_ARGB8888 and + DRM_FORMAT_ABGR8888 + +Android requires this. +As the underlying hardware doesn't support alpha blending, +we ignore the alpha value. + +Signed-off-by: Jan Kehren +--- + drivers/gpu/drm/rp1/rp1-dpi/rp1_dpi.c | 2 ++ + drivers/gpu/drm/rp1/rp1-dpi/rp1_dpi_hw.c | 12 ++++++++++++ + 2 files changed, 14 insertions(+) + +--- a/drivers/gpu/drm/rp1/rp1-dpi/rp1_dpi.c ++++ b/drivers/gpu/drm/rp1/rp1-dpi/rp1_dpi.c +@@ -260,6 +260,8 @@ static struct drm_driver rp1dpi_driver = + static const u32 rp1dpi_formats[] = { + DRM_FORMAT_XRGB8888, + DRM_FORMAT_XBGR8888, ++ DRM_FORMAT_ARGB8888, ++ DRM_FORMAT_ABGR8888, + DRM_FORMAT_RGB888, + DRM_FORMAT_BGR888, + DRM_FORMAT_RGB565 +--- a/drivers/gpu/drm/rp1/rp1-dpi/rp1_dpi_hw.c ++++ b/drivers/gpu/drm/rp1/rp1-dpi/rp1_dpi_hw.c +@@ -258,6 +258,18 @@ static const struct rp1dpi_ipixfmt my_fo + .rgbsz = BITS(DPI_DMA_RGBSZ_BPP, 3), + }, + { ++ .format = DRM_FORMAT_ARGB8888, ++ .mask = IMASK_RGB(0x3fc, 0x3fc, 0x3fc), ++ .shift = ISHIFT_RGB(23, 15, 7), ++ .rgbsz = BITS(DPI_DMA_RGBSZ_BPP, 3), ++ }, ++ { ++ .format = DRM_FORMAT_ABGR8888, ++ .mask = IMASK_RGB(0x3fc, 0x3fc, 0x3fc), ++ .shift = ISHIFT_RGB(7, 15, 23), ++ .rgbsz = BITS(DPI_DMA_RGBSZ_BPP, 3), ++ }, ++ { + .format = DRM_FORMAT_RGB888, + .mask = IMASK_RGB(0x3fc, 0x3fc, 0x3fc), + .shift = ISHIFT_RGB(23, 15, 7), diff --git a/target/linux/bcm27xx/patches-6.6/950-1224-drm-rp1-rp1-vec-Add-DRM_FORMAT_ARGB8888-and-DRM_FORM.patch b/target/linux/bcm27xx/patches-6.6/950-1224-drm-rp1-rp1-vec-Add-DRM_FORMAT_ARGB8888-and-DRM_FORM.patch new file mode 100644 index 00000000000..4c671cb6642 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1224-drm-rp1-rp1-vec-Add-DRM_FORMAT_ARGB8888-and-DRM_FORM.patch @@ -0,0 +1,48 @@ +From 29f7f01091f9aaa6b0c45f5c2e3db1792d381e9d Mon Sep 17 00:00:00 2001 +From: Jan Kehren +Date: Tue, 20 Aug 2024 08:16:06 +0000 +Subject: [PATCH 1224/1350] drm: rp1: rp1-vec: Add DRM_FORMAT_ARGB8888 and + DRM_FORMAT_ABGR8888 + +Android requires this. +As the underlying hardware doesn't support alpha blending, +we ignore the alpha value. + +Signed-off-by: Jan Kehren +--- + drivers/gpu/drm/rp1/rp1-vec/rp1_vec.c | 2 ++ + drivers/gpu/drm/rp1/rp1-vec/rp1_vec_hw.c | 12 ++++++++++++ + 2 files changed, 14 insertions(+) + +--- a/drivers/gpu/drm/rp1/rp1-vec/rp1_vec.c ++++ b/drivers/gpu/drm/rp1/rp1-vec/rp1_vec.c +@@ -420,6 +420,8 @@ static const struct drm_mode_config_func + static const u32 rp1vec_formats[] = { + DRM_FORMAT_XRGB8888, + DRM_FORMAT_XBGR8888, ++ DRM_FORMAT_ARGB8888, ++ DRM_FORMAT_ABGR8888, + DRM_FORMAT_RGB888, + DRM_FORMAT_BGR888, + DRM_FORMAT_RGB565 +--- a/drivers/gpu/drm/rp1/rp1-vec/rp1_vec_hw.c ++++ b/drivers/gpu/drm/rp1/rp1-vec/rp1_vec_hw.c +@@ -63,6 +63,18 @@ static const struct rp1vec_ipixfmt my_fo + .rgbsz = BITS(VEC_RGBSZ_BYTES_PER_PIXEL_MINUS1, 3), + }, + { ++ .format = DRM_FORMAT_ARGB8888, ++ .mask = MASK_RGB(0x3fc, 0x3fc, 0x3fc), ++ .shift = SHIFT_RGB(23, 15, 7), ++ .rgbsz = BITS(VEC_RGBSZ_BYTES_PER_PIXEL_MINUS1, 3), ++ }, ++ { ++ .format = DRM_FORMAT_ABGR8888, ++ .mask = MASK_RGB(0x3fc, 0x3fc, 0x3fc), ++ .shift = SHIFT_RGB(7, 15, 23), ++ .rgbsz = BITS(VEC_RGBSZ_BYTES_PER_PIXEL_MINUS1, 3), ++ }, ++ { + .format = DRM_FORMAT_RGB888, + .mask = MASK_RGB(0x3fc, 0x3fc, 0x3fc), + .shift = SHIFT_RGB(23, 15, 7), diff --git a/target/linux/bcm27xx/patches-6.6/950-1225-drm-vc4-Add-a-delay-after-disabling-hdmi-phy-output.patch b/target/linux/bcm27xx/patches-6.6/950-1225-drm-vc4-Add-a-delay-after-disabling-hdmi-phy-output.patch new file mode 100644 index 00000000000..b00330b6a24 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1225-drm-vc4-Add-a-delay-after-disabling-hdmi-phy-output.patch @@ -0,0 +1,34 @@ +From d984fd8907736d37656c558e213cfe087e43a7ce Mon Sep 17 00:00:00 2001 +From: Dom Cobley +Date: Mon, 12 Aug 2024 13:31:58 +0100 +Subject: [PATCH 1225/1350] drm/vc4: Add a delay after disabling hdmi phy + output + +There appears to be a requirement for some devices +(I'm testing with a 8K VRROOM 40Gbps HDMI switch) +for a measable delay between removing the hdmi phy output from +the old mode, to enabling the hdmi phy output for the new mode. + +Without the delay, a mode switch has a small change of getting a permanent +'no signal', which requires a subsequent mode switch or a unplug/replug +to redetect. + +Switching between 4kp24/25/30 modes fails about 5% of time in my testing. + +Add a delay to make it impossible to switch faster than this. + +Signed-off-by: Dom Cobley +--- + drivers/gpu/drm/vc4/vc4_crtc.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/gpu/drm/vc4/vc4_crtc.c ++++ b/drivers/gpu/drm/vc4/vc4_crtc.c +@@ -668,6 +668,7 @@ static void vc4_crtc_atomic_disable(stru + * someone was waiting it. + */ + vc4_crtc_send_vblank(crtc); ++ msleep(20); + } + + static void vc4_crtc_atomic_enable(struct drm_crtc *crtc, diff --git a/target/linux/bcm27xx/patches-6.6/950-1226-drm-vc4-Implement-vc6_hdmi_phy_disable.patch b/target/linux/bcm27xx/patches-6.6/950-1226-drm-vc4-Implement-vc6_hdmi_phy_disable.patch new file mode 100644 index 00000000000..527e815a86f --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1226-drm-vc4-Implement-vc6_hdmi_phy_disable.patch @@ -0,0 +1,25 @@ +From aa54ce17dc3a19eaf26f9c17c05a18aabcac90b0 Mon Sep 17 00:00:00 2001 +From: Dom Cobley +Date: Tue, 13 Aug 2024 16:13:16 +0100 +Subject: [PATCH 1226/1350] drm/vc4: Implement vc6_hdmi_phy_disable + +The body of this function was missing so we don't reset the phy +when disabling it. + +Signed-off-by: Dom Cobley +--- + drivers/gpu/drm/vc4/vc4_hdmi_phy.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/gpu/drm/vc4/vc4_hdmi_phy.c ++++ b/drivers/gpu/drm/vc4/vc4_hdmi_phy.c +@@ -1197,4 +1197,9 @@ void vc6_hdmi_phy_init(struct vc4_hdmi * + + void vc6_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi) + { ++ unsigned long flags; ++ ++ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); ++ vc6_hdmi_reset_phy(vc4_hdmi); ++ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); + } diff --git a/target/linux/bcm27xx/patches-6.6/950-1227-drm-vc4-Also-power-down-the-PLL-core-when-resetting-.patch b/target/linux/bcm27xx/patches-6.6/950-1227-drm-vc4-Also-power-down-the-PLL-core-when-resetting-.patch new file mode 100644 index 00000000000..67df065766a --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1227-drm-vc4-Also-power-down-the-PLL-core-when-resetting-.patch @@ -0,0 +1,35 @@ +From 3d21dabd055ca064880e775892a10c5e69fdf5e9 Mon Sep 17 00:00:00 2001 +From: Dom Cobley +Date: Tue, 13 Aug 2024 17:18:51 +0100 +Subject: [PATCH 1227/1350] drm/vc4: Also power down the PLL core when + resetting PHY + +The current reset code doesn't actually stop the hdmi output. +That makes it difficult for displays to handle a mode set. + +Powering down the PLL does actually remove the hdmi signal +and makes mode sets more reliable + +Signed-off-by: Dom Cobley +--- + drivers/gpu/drm/vc4/vc4_hdmi_phy.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/gpu/drm/vc4/vc4_hdmi_phy.c ++++ b/drivers/gpu/drm/vc4/vc4_hdmi_phy.c +@@ -137,6 +137,7 @@ + #define VC6_HDMI_TX_PHY_PLL_REFCLK_REFCLK_SEL_CMOS BIT(13) + #define VC6_HDMI_TX_PHY_PLL_REFCLK_REFFRQ_MASK VC4_MASK(9, 0) + ++#define VC6_HDMI_TX_PHY_PLL_POST_KDIV_BYPASS_EN BIT(4) + #define VC6_HDMI_TX_PHY_PLL_POST_KDIV_CLK0_SEL_MASK VC4_MASK(3, 2) + #define VC6_HDMI_TX_PHY_PLL_POST_KDIV_KDIV_MASK VC4_MASK(1, 0) + +@@ -947,6 +948,7 @@ static void vc6_hdmi_reset_phy(struct vc + + HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0); + HDMI_WRITE(HDMI_TX_PHY_POWERUP_CTL, 0); ++ HDMI_WRITE(HDMI_TX_PHY_PLL_POST_KDIV, VC6_HDMI_TX_PHY_PLL_POST_KDIV_BYPASS_EN); + } + + void vc6_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi, diff --git a/target/linux/bcm27xx/patches-6.6/950-1228-ASoC-add-driver-for-new-HiFiBerry-ADC-only-board-s.patch b/target/linux/bcm27xx/patches-6.6/950-1228-ASoC-add-driver-for-new-HiFiBerry-ADC-only-board-s.patch new file mode 100644 index 00000000000..099d37e3ddd --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1228-ASoC-add-driver-for-new-HiFiBerry-ADC-only-board-s.patch @@ -0,0 +1,228 @@ +From 784ef64631be19ef45a597e618c04a0f8b041307 Mon Sep 17 00:00:00 2001 +From: j-schambacher +Date: Tue, 20 Aug 2024 10:08:27 +0200 +Subject: [PATCH 1228/1350] ASoC: add driver for new HiFiBerry ADC only + board(s) + +Adds the driver for the soon to be released first ADC only board. +It includes the same ADC controls as used by the DAC+ADC Pro driver. + +Signed-off-by: j-schambacher +--- + sound/soc/bcm/Kconfig | 7 ++ + sound/soc/bcm/Makefile | 2 + + sound/soc/bcm/hifiberry_adc.c | 174 ++++++++++++++++++++++++++++++++++ + 3 files changed, 183 insertions(+) + create mode 100644 sound/soc/bcm/hifiberry_adc.c + +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -39,6 +39,13 @@ config SND_BCM2708_SOC_GOOGLEVOICEHAT_SO + help + Say Y or M if you want to add support for voiceHAT soundcard. + ++config SND_BCM2708_SOC_HIFIBERRY_ADC ++ tristate "Support for HifiBerry ADC" ++ select SND_SOC_PCM186X_I2C ++ select SND_RPI_HIFIBERRY_ADC ++ help ++ Say Y or M if you want to add support for HifiBerry ADC. ++ + config SND_BCM2708_SOC_HIFIBERRY_DAC + tristate "Support for HifiBerry DAC and DAC8X" + select SND_SOC_PCM5102A +--- a/sound/soc/bcm/Makefile ++++ b/sound/soc/bcm/Makefile +@@ -18,6 +18,7 @@ obj-$(CONFIG_SND_BCM63XX_I2S_WHISTLER) + + snd-soc-googlevoicehat-codec-objs := googlevoicehat-codec.o + + # BCM2708 Machine Support ++snd-soc-hifiberry-adc-objs := hifiberry_adc.o + snd-soc-hifiberry-dacplus-objs := hifiberry_dacplus.o + snd-soc-hifiberry-dacplushd-objs := hifiberry_dacplushd.o + snd-soc-hifiberry-dacplusadc-objs := hifiberry_dacplusadc.o +@@ -51,6 +52,7 @@ snd-soc-chipdip-dac-objs := chipdip-dac. + snd-soc-dacberry400-objs := dacberry400.o + + obj-$(CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD) += snd-soc-googlevoicehat-codec.o ++obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_ADC) += snd-soc-hifiberry-adc.o + obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += snd-soc-hifiberry-dacplus.o + obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUSHD) += snd-soc-hifiberry-dacplushd.o + obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUSADC) += snd-soc-hifiberry-dacplusadc.o +--- /dev/null ++++ b/sound/soc/bcm/hifiberry_adc.c +@@ -0,0 +1,174 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * ASoC Driver for HiFiBerry ADC ++ * ++ * Author: Joerg Schambacher ++ * Copyright 2024 ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "../codecs/pcm186x.h" ++#include "hifiberry_adc_controls.h" ++ ++static bool leds_off; ++ ++static int pcm1863_add_controls(struct snd_soc_component *component) ++{ ++ snd_soc_add_component_controls(component, ++ pcm1863_snd_controls_card, ++ ARRAY_SIZE(pcm1863_snd_controls_card)); ++ return 0; ++} ++ ++static int snd_rpi_hifiberry_adc_init(struct snd_soc_pcm_runtime *rtd) ++{ ++ struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); ++ struct snd_soc_component *adc = codec_dai->component; ++ int ret; ++ ++ ret = pcm1863_add_controls(adc); ++ if (ret < 0) ++ dev_warn(rtd->dev, "Failed to add pcm1863 controls: %d\n", ++ ret); ++ ++ codec_dai->driver->capture.rates = ++ SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | ++ SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | ++ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000; ++ ++ /* set GPIO2 to output, GPIO3 input */ ++ snd_soc_component_write(adc, PCM186X_GPIO3_2_CTRL, 0x00); ++ snd_soc_component_write(adc, PCM186X_GPIO3_2_DIR_CTRL, 0x04); ++ if (leds_off) ++ snd_soc_component_update_bits(adc, PCM186X_GPIO_IN_OUT, 0x40, 0x00); ++ else ++ snd_soc_component_update_bits(adc, PCM186X_GPIO_IN_OUT, 0x40, 0x40); ++ ++ return 0; ++} ++ ++static int snd_rpi_hifiberry_adc_hw_params( ++ struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) ++{ ++ int ret = 0; ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ int channels = params_channels(params); ++ int width = snd_pcm_format_width(params_format(params)); ++ ++ /* Using powers of 2 allows for an integer clock divisor */ ++ width = width <= 16 ? 16 : 32; ++ ++ ret = snd_soc_dai_set_bclk_ratio(asoc_rtd_to_cpu(rtd, 0), channels * width); ++ return ret; ++} ++ ++/* machine stream operations */ ++static const struct snd_soc_ops snd_rpi_hifiberry_adc_ops = { ++ .hw_params = snd_rpi_hifiberry_adc_hw_params, ++}; ++ ++SND_SOC_DAILINK_DEFS(hifi, ++ DAILINK_COMP_ARRAY(COMP_CPU("bcm2708-i2s.0")), ++ DAILINK_COMP_ARRAY(COMP_CODEC("pcm186x.1-004a", "pcm1863-aif")), ++ DAILINK_COMP_ARRAY(COMP_PLATFORM("bcm2708-i2s.0"))); ++ ++static struct snd_soc_dai_link snd_rpi_hifiberry_adc_dai[] = { ++{ ++ .name = "HiFiBerry ADC", ++ .stream_name = "HiFiBerry ADC HiFi", ++ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBS_CFS, ++ .ops = &snd_rpi_hifiberry_adc_ops, ++ .init = snd_rpi_hifiberry_adc_init, ++ SND_SOC_DAILINK_REG(hifi), ++}, ++}; ++ ++/* audio machine driver */ ++static struct snd_soc_card snd_rpi_hifiberry_adc = { ++ .name = "snd_rpi_hifiberry_adc", ++ .driver_name = "HifiberryAdc", ++ .owner = THIS_MODULE, ++ .dai_link = snd_rpi_hifiberry_adc_dai, ++ .num_links = ARRAY_SIZE(snd_rpi_hifiberry_adc_dai), ++}; ++ ++static int snd_rpi_hifiberry_adc_probe(struct platform_device *pdev) ++{ ++ int ret = 0, i = 0; ++ struct snd_soc_card *card = &snd_rpi_hifiberry_adc; ++ ++ snd_rpi_hifiberry_adc.dev = &pdev->dev; ++ if (pdev->dev.of_node) { ++ struct device_node *i2s_node; ++ struct snd_soc_dai_link *dai; ++ ++ dai = &snd_rpi_hifiberry_adc_dai[0]; ++ i2s_node = of_parse_phandle(pdev->dev.of_node, ++ "i2s-controller", 0); ++ if (i2s_node) { ++ for (i = 0; i < card->num_links; i++) { ++ dai->cpus->dai_name = NULL; ++ dai->cpus->of_node = i2s_node; ++ dai->platforms->name = NULL; ++ dai->platforms->of_node = i2s_node; ++ } ++ } ++ } ++ leds_off = of_property_read_bool(pdev->dev.of_node, ++ "hifiberry-adc,leds_off"); ++ ret = snd_soc_register_card(&snd_rpi_hifiberry_adc); ++ if (ret && ret != -EPROBE_DEFER) ++ dev_err(&pdev->dev, ++ "snd_soc_register_card() failed: %d\n", ret); ++ ++ return ret; ++} ++ ++static const struct of_device_id snd_rpi_hifiberry_adc_of_match[] = { ++ { .compatible = "hifiberry,hifiberry-adc", }, ++ {}, ++}; ++ ++MODULE_DEVICE_TABLE(of, snd_rpi_hifiberry_adc_of_match); ++ ++static struct platform_driver snd_rpi_hifiberry_adc_driver = { ++ .driver = { ++ .name = "snd-rpi-hifiberry-adc", ++ .owner = THIS_MODULE, ++ .of_match_table = snd_rpi_hifiberry_adc_of_match, ++ }, ++ .probe = snd_rpi_hifiberry_adc_probe, ++}; ++ ++module_platform_driver(snd_rpi_hifiberry_adc_driver); ++ ++MODULE_AUTHOR("Joerg Schambacher "); ++MODULE_DESCRIPTION("ASoC Driver for HiFiBerry ADC"); ++MODULE_LICENSE("GPL"); diff --git a/target/linux/bcm27xx/patches-6.6/950-1229-overlays-Add-overlay-for-Hifiberry-ADC.patch b/target/linux/bcm27xx/patches-6.6/950-1229-overlays-Add-overlay-for-Hifiberry-ADC.patch new file mode 100644 index 00000000000..b1e76316832 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1229-overlays-Add-overlay-for-Hifiberry-ADC.patch @@ -0,0 +1,100 @@ +From 2f656dc533b65ae7f23527c3dc176efa92add105 Mon Sep 17 00:00:00 2001 +From: j-schambacher +Date: Tue, 20 Aug 2024 10:24:10 +0200 +Subject: [PATCH 1229/1350] overlays: Add overlay for Hifiberry ADC + +Adds the DT overlay for the HiFiBerry ADC. + +Signed-off-by: j-schambacher +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 7 +++ + .../dts/overlays/hifiberry-adc-overlay.dts | 45 +++++++++++++++++++ + sound/soc/bcm/Kconfig | 1 + + 4 files changed, 54 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/hifiberry-adc-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -85,6 +85,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + hd44780-i2c-lcd.dtbo \ + hd44780-lcd.dtbo \ + hdmi-backlight-hwhack-gpio.dtbo \ ++ hifiberry-adc.dtbo \ + hifiberry-amp.dtbo \ + hifiberry-amp100.dtbo \ + hifiberry-amp3.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1771,6 +1771,13 @@ Params: gpio_pin GPIO pin + expects a high to switch it on. + + ++Name: hifiberry-adc ++Info: Configures the HifiBerry ADC audio card ++Load: dtoverlay=hifiberry-adc,= ++Params: leds_off If set to 'true' the onboard indicator LED ++ is switched off at all times. ++ ++ + Name: hifiberry-amp + Info: Configures the HifiBerry Amp and Amp+ audio cards + Load: dtoverlay=hifiberry-amp +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/hifiberry-adc-overlay.dts +@@ -0,0 +1,45 @@ ++// SPDX-License-Identifier: GPL-2.0 ++// Definitions for HiFiBerry ADC, no onboard clocks ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835"; ++ ++ fragment@0 { ++ target = <&i2s_clk_producer>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ hb_adc: pcm186x@4a { ++ #sound-dai-cells = <0>; ++ compatible = "ti,pcm1863"; ++ reg = <0x4a>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&sound>; ++ hifiberry_adc: __overlay__ { ++ compatible = "hifiberry,hifiberry-adc"; ++ audio-codec = <&hb_adc>; ++ i2s-controller = <&i2s_clk_producer>; ++ status = "okay"; ++ }; ++ }; ++ ++ __overrides__ { ++ leds_off = <&hifiberry_adc>,"hifiberry-adc,leds_off?"; ++ }; ++}; +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -45,6 +45,7 @@ config SND_BCM2708_SOC_HIFIBERRY_ADC + select SND_RPI_HIFIBERRY_ADC + help + Say Y or M if you want to add support for HifiBerry ADC. ++ Use this module for HiFiBerry's ADC-only sound cards + + config SND_BCM2708_SOC_HIFIBERRY_DAC + tristate "Support for HifiBerry DAC and DAC8X" diff --git a/target/linux/bcm27xx/patches-6.6/950-0320-spi-spidev-Restore-loading-from-Device-Tree.patch b/target/linux/bcm27xx/patches-6.6/950-1232-spi-spidev-Restore-loading-from-Device-Tree.patch similarity index 60% rename from target/linux/bcm27xx/patches-6.6/950-0320-spi-spidev-Restore-loading-from-Device-Tree.patch rename to target/linux/bcm27xx/patches-6.6/950-1232-spi-spidev-Restore-loading-from-Device-Tree.patch index da1bbb78866..8384559dad2 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0320-spi-spidev-Restore-loading-from-Device-Tree.patch +++ b/target/linux/bcm27xx/patches-6.6/950-1232-spi-spidev-Restore-loading-from-Device-Tree.patch @@ -1,7 +1,7 @@ -From 2f223e0e4931486fbc32df3c89bc16ff1ca434bf Mon Sep 17 00:00:00 2001 +From ba0f2212e0e100ee16bdde76b7efca6bb8ee9446 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 29 Nov 2021 12:14:49 +0000 -Subject: [PATCH 0320/1085] spi: spidev: Restore loading from Device Tree +Subject: [PATCH 1232/1350] spi: spidev: Restore loading from Device Tree As happens occasionally, an upstream change has once again prevented spidev from being loaded via Device Tree. We now need "spidev" to be @@ -15,11 +15,11 @@ Signed-off-by: Phil Elwell --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c -@@ -699,6 +699,7 @@ static const struct file_operations spid - static struct class *spidev_class; - - static const struct spi_device_id spidev_spi_ids[] = { +@@ -711,6 +711,7 @@ static const struct spi_device_id spidev + { .name = "spi-authenta" }, + { .name = "em3581" }, + { .name = "si3210" }, + { .name = "spidev" }, - { .name = "bh2228fv" }, - { .name = "dh2228fv" }, - { .name = "jg10309-01" }, + {}, + }; + MODULE_DEVICE_TABLE(spi, spidev_spi_ids); diff --git a/target/linux/bcm27xx/patches-6.6/950-1233-drivers-drm-rp1-dsi-Implement-more-DSI-options-and-f.patch b/target/linux/bcm27xx/patches-6.6/950-1233-drivers-drm-rp1-dsi-Implement-more-DSI-options-and-f.patch new file mode 100644 index 00000000000..e906ad80272 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1233-drivers-drm-rp1-dsi-Implement-more-DSI-options-and-f.patch @@ -0,0 +1,242 @@ +From e596d70725ca70113d39d9366d7b4d3e492f6449 Mon Sep 17 00:00:00 2001 +From: Nick Hollinghurst +Date: Wed, 31 Jul 2024 19:05:29 +0100 +Subject: [PATCH 1233/1350] drivers: drm: rp1-dsi: Implement more DSI options + and flags + +Now implementing: +- Per-command selection of LP or HS for commands (previously LP) +- EoTp transmission option (previously EoTp was always disabled) +- Non-continuous clock option (previously always continuous) +- Per-command enabling of ACK request (in command mode only) + +Make a plausible (and possibly correct) attempt to measure the +longest LP command that will fit into vertical blanking lines. + +DON'T set both "Burst Mode" and "Sync Events" flags together. +This is redundant in the standard IP; in this RP1 variant it +would enable Sync Pulses but may break with some video timings. + +Signed-off-by: Nick Hollinghurst +--- + drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi.c | 5 +- + drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi.h | 3 +- + drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi_dsi.c | 106 +++++++++++++++++----- + 3 files changed, 91 insertions(+), 23 deletions(-) + +--- a/drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi.c ++++ b/drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi.c +@@ -396,7 +396,10 @@ ssize_t rp1dsi_host_transfer(struct mipi + return ret; + } + +- rp1dsi_dsi_send(dsi, *(u32 *)(&packet.header), packet.payload_length, packet.payload); ++ rp1dsi_dsi_send(dsi, *(u32 *)(&packet.header), ++ packet.payload_length, packet.payload, ++ !!(msg->flags & MIPI_DSI_MSG_USE_LPM), ++ !!(msg->flags & MIPI_DSI_MSG_REQ_ACK)); + + /* Optional read back */ + if (msg->rx_len && msg->rx_buf) +--- a/drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi.h ++++ b/drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi.h +@@ -86,7 +86,8 @@ void rp1dsi_mipicfg_setup(struct rp1_dsi + /* Functions to control the SNPS D-PHY and DSI block setup */ + + void rp1dsi_dsi_setup(struct rp1_dsi *dsi, struct drm_display_mode const *mode); +-void rp1dsi_dsi_send(struct rp1_dsi *dsi, u32 header, int len, const u8 *buf); ++void rp1dsi_dsi_send(struct rp1_dsi *dsi, u32 header, int len, const u8 *buf, ++ bool use_lpm, bool req_ack); + int rp1dsi_dsi_recv(struct rp1_dsi *dsi, int len, u8 *buf); + void rp1dsi_dsi_set_cmdmode(struct rp1_dsi *dsi, int cmd_mode); + void rp1dsi_dsi_stop(struct rp1_dsi *dsi); +--- a/drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi_dsi.c ++++ b/drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi_dsi.c +@@ -103,6 +103,24 @@ + + /* And some bitfield definitions */ + ++#define DSI_PCKHDL_EOTP_TX_EN BIT(0) ++#define DSI_PCKHDL_BTA_EN BIT(2) ++ ++#define DSI_VID_MODE_LP_CMD_EN BIT(15) ++#define DSI_VID_MODE_FRAME_BTA_ACK_EN BIT(14) ++#define DSI_VID_MODE_LP_HFP_EN BIT(13) ++#define DSI_VID_MODE_LP_HBP_EN BIT(12) ++#define DSI_VID_MODE_LP_VACT_EN BIT(11) ++#define DSI_VID_MODE_LP_VFP_EN BIT(10) ++#define DSI_VID_MODE_LP_VBP_EN BIT(9) ++#define DSI_VID_MODE_LP_VSA_EN BIT(8) ++#define DSI_VID_MODE_SYNC_PULSES 0 ++#define DSI_VID_MODE_SYNC_EVENTS 1 ++#define DSI_VID_MODE_BURST 2 ++ ++#define DSI_CMD_MODE_ALL_LP 0x10f7f00 ++#define DSI_CMD_MODE_ACK_RQST_EN BIT(1) ++ + #define DPHY_PWR_UP_SHUTDOWNZ_LSB 0 + #define DPHY_PWR_UP_SHUTDOWNZ_BITS BIT(DPHY_PWR_UP_SHUTDOWNZ_LSB) + +@@ -1252,8 +1270,8 @@ static u32 dphy_configure_pll(struct rp1 + vco_freq, actual_vco_freq, m, refclk, n, + hsfreq_table[dsi->hsfreq_index].hsfreqrange); + } else { +- drm_warn(dsi->drm, +- "rp1dsi: Error configuring DPHY PLL %uHz\n", vco_freq); ++ drm_err(dsi->drm, ++ "rp1dsi: Error configuring DPHY PLL %uHz\n", vco_freq); + } + + return actual_vco_freq; +@@ -1321,7 +1339,7 @@ static void rp1dsi_dpiclk_start(struct r + clk_set_rate(dsi->clocks[RP1DSI_CLOCK_DPI], (4 * lanes * byte_clock) / (bpp >> 1)); + clk_prepare_enable(dsi->clocks[RP1DSI_CLOCK_DPI]); + drm_info(dsi->drm, +- "rp1dsi: Nominal Byte clock %u DPI clock %lu (parent rate %lu)", ++ "rp1dsi: Nominal Byte clock %u DPI clock %lu (parent rate %lu)\n", + byte_clock, + clk_get_rate(dsi->clocks[RP1DSI_CLOCK_DPI]), + clk_get_rate(clk_get_parent(dsi->clocks[RP1DSI_CLOCK_DPI]))); +@@ -1365,7 +1383,8 @@ static u32 get_colorcode(enum mipi_dsi_p + + void rp1dsi_dsi_setup(struct rp1_dsi *dsi, struct drm_display_mode const *mode) + { +- u32 timeout, mask, vid_mode_cfg; ++ int cmdtim; ++ u32 timeout, mask, clkdiv; + unsigned int bpp = mipi_dsi_pixel_format_to_bpp(dsi->display_format); + u32 byte_clock = clamp((bpp * 125 * min(mode->clock, RP1DSI_DPI_MAX_KHZ)) / dsi->lanes, + RP1DSI_BYTE_CLK_MIN, RP1DSI_BYTE_CLK_MAX); +@@ -1374,19 +1393,31 @@ void rp1dsi_dsi_setup(struct rp1_dsi *ds + DSI_WRITE(DSI_DPI_CFG_POL, 0); + DSI_WRITE(DSI_GEN_VCID, dsi->vc); + DSI_WRITE(DSI_DPI_COLOR_CODING, get_colorcode(dsi->display_format)); +- /* a conservative guess (LP escape is slow!) */ +- DSI_WRITE(DSI_DPI_LP_CMD_TIM, 0x00100000); + +- /* Drop to LP where possible; use LP Escape for all commands */ +- vid_mode_cfg = 0xbf00; +- if (!(dsi->display_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)) +- vid_mode_cfg |= 0x01; +- else if (8 * dsi->lanes > bpp) +- vid_mode_cfg &= ~0x400; /* PULSE && inexact DPICLK => fix HBP time */ ++ /* ++ * Flags to configure use of LP, EoTp, Burst Mode, Sync Events/Pulses. ++ * Note that Burst Mode implies Sync Events; the two flags need not be ++ * set concurrently, and in this RP1 variant *should not* both be set: ++ * doing so would (counter-intuitively) enable Sync Pulses and may fail ++ * if there is not sufficient time to return to LP11 state during HBP. ++ */ ++ mask = DSI_VID_MODE_LP_HFP_EN | DSI_VID_MODE_LP_HBP_EN | ++ DSI_VID_MODE_LP_VACT_EN | DSI_VID_MODE_LP_VFP_EN | ++ DSI_VID_MODE_LP_VBP_EN | DSI_VID_MODE_LP_VSA_EN; ++ if (dsi->display_flags & MIPI_DSI_MODE_LPM) ++ mask |= DSI_VID_MODE_LP_CMD_EN; + if (dsi->display_flags & MIPI_DSI_MODE_VIDEO_BURST) +- vid_mode_cfg |= 0x02; +- DSI_WRITE(DSI_VID_MODE_CFG, vid_mode_cfg); +- DSI_WRITE(DSI_CMD_MODE_CFG, 0x10F7F00); ++ mask |= DSI_VID_MODE_BURST; ++ else if (!(dsi->display_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)) ++ mask |= DSI_VID_MODE_SYNC_EVENTS; ++ else if (8 * dsi->lanes > bpp) ++ mask &= ~DSI_VID_MODE_LP_HBP_EN; /* PULSE && inexact DPICLK => fix HBP time */ ++ DSI_WRITE(DSI_VID_MODE_CFG, mask); ++ DSI_WRITE(DSI_CMD_MODE_CFG, ++ (dsi->display_flags & MIPI_DSI_MODE_LPM) ? DSI_CMD_MODE_ALL_LP : 0); ++ DSI_WRITE(DSI_PCKHDL_CFG, ++ DSI_PCKHDL_BTA_EN | ++ ((dsi->display_flags & MIPI_DSI_MODE_NO_EOT_PACKET) ? 0 : DSI_PCKHDL_EOTP_TX_EN)); + + /* Select Command Mode */ + DSI_WRITE(DSI_MODE_CFG, 1); +@@ -1397,9 +1428,9 @@ void rp1dsi_dsi_setup(struct rp1_dsi *ds + timeout = 0; + DSI_WRITE(DSI_TO_CNT_CFG, (timeout << 16) | RP1DSI_LPRX_TO_VAL); + DSI_WRITE(DSI_BTA_TO_CNT, RP1DSI_BTA_TO_VAL); ++ clkdiv = max(2u, 1u + byte_clock / RP1DSI_ESC_CLK_MAX); /* byte clocks per escape clock */ + DSI_WRITE(DSI_CLKMGR_CFG, +- (RP1DSI_TO_CLK_DIV << 8) | +- max(2u, 1u + byte_clock / RP1DSI_ESC_CLK_MAX)); ++ (RP1DSI_TO_CLK_DIV << 8) | clkdiv); + + /* Configure video timings */ + DSI_WRITE(DSI_VID_PKT_SIZE, mode->hdisplay); +@@ -1425,6 +1456,18 @@ void rp1dsi_dsi_setup(struct rp1_dsi *ds + (hsfreq_table[dsi->hsfreq_index].data_lp2hs << DSI_PHY_TMR_LP2HS_LSB) | + (hsfreq_table[dsi->hsfreq_index].data_hs2lp << DSI_PHY_TMR_HS2LP_LSB)); + ++ /* Estimate how many LP bytes can be sent during vertical blanking (Databook 3.6.2.1) */ ++ cmdtim = mode->htotal; ++ if (dsi->display_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) ++ cmdtim -= mode->hsync_end - mode->hsync_start; ++ cmdtim = (bpp * cmdtim - 64) / (8 * dsi->lanes); /* byte clocks after HSS and EoTp */ ++ cmdtim -= hsfreq_table[dsi->hsfreq_index].data_hs2lp; ++ cmdtim -= hsfreq_table[dsi->hsfreq_index].data_lp2hs; ++ cmdtim = (cmdtim / clkdiv) - 24; /* escape clocks for commands */ ++ cmdtim = max(0, cmdtim >> 4); /* bytes (at 2 clocks per bit) */ ++ drm_info(dsi->drm, "rp1dsi: Command time (outvact): %d\n", cmdtim); ++ DSI_WRITE(DSI_DPI_LP_CMD_TIM, cmdtim << 16); ++ + /* Wait for PLL lock */ + for (timeout = (1 << 14); timeout != 0; --timeout) { + usleep_range(10, 50); +@@ -1434,9 +1477,9 @@ void rp1dsi_dsi_setup(struct rp1_dsi *ds + if (timeout == 0) + drm_err(dsi->drm, "RP1DSI: Time out waiting for PLL\n"); + +- DSI_WRITE(DSI_LPCLK_CTRL, 0x1); /* configure the requesthsclk */ ++ DSI_WRITE(DSI_LPCLK_CTRL, ++ (dsi->display_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) ? 0x3 : 0x1); + DSI_WRITE(DSI_PHY_TST_CTRL0, 0x2); +- DSI_WRITE(DSI_PCKHDL_CFG, 1 << 2); /* allow bus turnaround */ + DSI_WRITE(DSI_PWR_UP, 0x1); /* power up */ + + /* Now it should be safe to start the external DPI clock divider */ +@@ -1460,7 +1503,8 @@ void rp1dsi_dsi_setup(struct rp1_dsi *ds + mask, DSI_READ(DSI_PHY_STATUS)); + } + +-void rp1dsi_dsi_send(struct rp1_dsi *dsi, u32 hdr, int len, const u8 *buf) ++void rp1dsi_dsi_send(struct rp1_dsi *dsi, u32 hdr, int len, const u8 *buf, ++ bool use_lpm, bool req_ack) + { + u32 val; + +@@ -1471,6 +1515,24 @@ void rp1dsi_dsi_send(struct rp1_dsi *dsi + usleep_range(100, 150); + } + ++ /* ++ * Update global configuration flags for LP/HS and ACK options. ++ * XXX It's not clear if having empty FIFOs (checked above and below) guarantees that ++ * the last command has completed and been ACKed, or how closely these control registers ++ * align with command/payload FIFO writes (as each is an independent clock-crossing)? ++ */ ++ val = DSI_READ(DSI_VID_MODE_CFG); ++ if (use_lpm) ++ val |= DSI_VID_MODE_LP_CMD_EN; ++ else ++ val &= ~DSI_VID_MODE_LP_CMD_EN; ++ DSI_WRITE(DSI_VID_MODE_CFG, val); ++ val = (use_lpm) ? DSI_CMD_MODE_ALL_LP : 0; ++ if (req_ack) ++ val |= DSI_CMD_MODE_ACK_RQST_EN; ++ DSI_WRITE(DSI_CMD_MODE_CFG, val); ++ (void)DSI_READ(DSI_CMD_MODE_CFG); ++ + /* Write payload (in 32-bit words) and header */ + for (; len > 0; len -= 4) { + val = *buf++; +@@ -1504,8 +1566,10 @@ int rp1dsi_dsi_recv(struct rp1_dsi *dsi, + break; + usleep_range(100, 150); + } +- if (i == 0) ++ if (!i) { ++ drm_warn(dsi->drm, "Receive failed\n"); + return -EIO; ++ } + + for (i = 0; i < len; i += 4) { + /* Read fifo must not be empty before all bytes are read */ diff --git a/target/linux/bcm27xx/patches-6.6/950-1234-rtc-pcf8523-Fix-oscillator-stop-bit-handling-reading.patch b/target/linux/bcm27xx/patches-6.6/950-1234-rtc-pcf8523-Fix-oscillator-stop-bit-handling-reading.patch new file mode 100644 index 00000000000..8b634117d2a --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1234-rtc-pcf8523-Fix-oscillator-stop-bit-handling-reading.patch @@ -0,0 +1,53 @@ +From 8beb6891489c3c99618a7390578109aadfdf8901 Mon Sep 17 00:00:00 2001 +From: Axel <48924884+Paladinking@users.noreply.github.com> +Date: Wed, 28 Aug 2024 09:46:13 +0200 +Subject: [PATCH 1234/1350] rtc: pcf8523: Fix oscillator stop bit handling + reading from Control_1 + +The check if the oscillator stop bit is set was reading from Control_1 +register instead of the Seconds register. +This caused the Seconds register to be incorrectly changed if bit 7 of +Control_1 happens to be set. + +Signed-off-by: Axel Hammarberg +--- + drivers/rtc/rtc-pcf8523.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/drivers/rtc/rtc-pcf8523.c ++++ b/drivers/rtc/rtc-pcf8523.c +@@ -108,10 +108,10 @@ static int pcf8523_rtc_read_time(struct + if (err < 0) + return err; + +- if ((regs[0] & PCF8523_CONTROL1_STOP) || (regs[3] & PCF8523_SECONDS_OS)) ++ if (regs[PCF8523_REG_CONTROL1] & PCF8523_CONTROL1_STOP) + return -EINVAL; + +- if (regs[0] & PCF8523_SECONDS_OS) { ++ if (regs[PCF8523_REG_SECONDS] & PCF8523_SECONDS_OS) { + /* + * If the oscillator was stopped, try to clear the flag. Upon + * power-up the flag is always set, but if we cannot clear it +@@ -120,10 +120,10 @@ static int pcf8523_rtc_read_time(struct + * that the clock cannot be assumed to be correct. + */ + +- regs[0] &= ~PCF8523_SECONDS_OS; ++ regs[PCF8523_REG_SECONDS] &= ~PCF8523_SECONDS_OS; + + err = regmap_write(pcf8523->regmap, PCF8523_REG_SECONDS, +- regs[0]); ++ regs[PCF8523_REG_SECONDS]); + if (err < 0) + return err; + +@@ -135,7 +135,7 @@ static int pcf8523_rtc_read_time(struct + if (value & PCF8523_SECONDS_OS) + return -EAGAIN; + +- regs[0] = value; ++ regs[PCF8523_REG_SECONDS] = value; + } + + tm->tm_sec = bcd2bin(regs[3] & 0x7f); diff --git a/target/linux/bcm27xx/patches-6.6/950-1235-drivers-media-pci-Update-Hailo-accelerator-device-dr.patch b/target/linux/bcm27xx/patches-6.6/950-1235-drivers-media-pci-Update-Hailo-accelerator-device-dr.patch new file mode 100644 index 00000000000..5f8cf8df017 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1235-drivers-media-pci-Update-Hailo-accelerator-device-dr.patch @@ -0,0 +1,3352 @@ +From a44f17d8193b69aedb1beebf5ad885a88b1c6615 Mon Sep 17 00:00:00 2001 +From: Naushir Patuck +Date: Fri, 2 Aug 2024 11:01:24 +0100 +Subject: [PATCH 1235/1350] drivers: media: pci: Update Hailo accelerator + device driver to v4.18.0 + +Sourced from https://github.com/hailo-ai/hailort-drivers/ + +Signed-off-by: Naushir Patuck +--- + drivers/media/pci/hailo/Makefile | 2 + + drivers/media/pci/hailo/common/fw_operation.c | 2 +- + drivers/media/pci/hailo/common/fw_operation.h | 2 +- + .../media/pci/hailo/common/fw_validation.c | 10 +- + .../media/pci/hailo/common/fw_validation.h | 5 +- + .../pci/hailo/common/hailo_ioctl_common.h | 240 +++++++---- + .../media/pci/hailo/common/hailo_resource.c | 2 +- + .../media/pci/hailo/common/hailo_resource.h | 2 +- + drivers/media/pci/hailo/common/pcie_common.c | 367 +++++++++++++---- + drivers/media/pci/hailo/common/pcie_common.h | 42 +- + drivers/media/pci/hailo/common/utils.h | 24 +- + drivers/media/pci/hailo/common/vdma_common.c | 371 +++++++++++++----- + drivers/media/pci/hailo/common/vdma_common.h | 34 +- + drivers/media/pci/hailo/src/fops.c | 104 +++-- + drivers/media/pci/hailo/src/fops.h | 1 + + drivers/media/pci/hailo/src/pci_soc_ioctl.c | 155 ++++++++ + drivers/media/pci/hailo/src/pci_soc_ioctl.h | 19 + + drivers/media/pci/hailo/src/pcie.c | 93 ++++- + drivers/media/pci/hailo/src/pcie.h | 2 + + drivers/media/pci/hailo/src/sysfs.c | 9 + + drivers/media/pci/hailo/src/utils.c | 1 - + .../pci/hailo/utils/integrated_nnc_utils.c | 101 +++++ + .../pci/hailo/utils/integrated_nnc_utils.h | 30 ++ + drivers/media/pci/hailo/vdma/ioctl.c | 53 ++- + drivers/media/pci/hailo/vdma/ioctl.h | 6 +- + drivers/media/pci/hailo/vdma/memory.c | 148 ++++++- + drivers/media/pci/hailo/vdma/memory.h | 4 +- + drivers/media/pci/hailo/vdma/vdma.c | 80 ++-- + drivers/media/pci/hailo/vdma/vdma.h | 30 +- + 29 files changed, 1536 insertions(+), 403 deletions(-) + create mode 100755 drivers/media/pci/hailo/src/pci_soc_ioctl.c + create mode 100755 drivers/media/pci/hailo/src/pci_soc_ioctl.h + create mode 100755 drivers/media/pci/hailo/utils/integrated_nnc_utils.c + create mode 100755 drivers/media/pci/hailo/utils/integrated_nnc_utils.h + +--- a/drivers/media/pci/hailo/Makefile ++++ b/drivers/media/pci/hailo/Makefile +@@ -10,6 +10,7 @@ hailo_pci-objs += src/pcie.o + hailo_pci-objs += src/fops.o + hailo_pci-objs += src/utils.o + hailo_pci-objs += src/sysfs.o ++hailo_pci-objs += src/pci_soc_ioctl.o + + hailo_pci-objs += $(COMMON_SRC_DIRECTORY)/fw_validation.o + hailo_pci-objs += $(COMMON_SRC_DIRECTORY)/fw_operation.o +@@ -18,6 +19,7 @@ hailo_pci-objs += $(COMMON_SRC_DIRECTORY + hailo_pci-objs += $(COMMON_SRC_DIRECTORY)/hailo_resource.o + + hailo_pci-objs += $(UTILS_SRC_DIRECTORY)/logs.o ++hailo_pci-objs += $(UTILS_SRC_DIRECTORY)/integrated_nnc_utils.o + + hailo_pci-objs += $(VDMA_SRC_DIRECTORY)/vdma.o + hailo_pci-objs += $(VDMA_SRC_DIRECTORY)/memory.o +--- a/drivers/media/pci/hailo/common/fw_operation.c ++++ b/drivers/media/pci/hailo/common/fw_operation.c +@@ -1,4 +1,4 @@ +-// SPDX-License-Identifier: GPL-2.0 ++// SPDX-License-Identifier: MIT + /** + * Copyright (c) 2022 Hailo Technologies Ltd. All rights reserved. + **/ +--- a/drivers/media/pci/hailo/common/fw_operation.h ++++ b/drivers/media/pci/hailo/common/fw_operation.h +@@ -1,4 +1,4 @@ +-// SPDX-License-Identifier: GPL-2.0 ++// SPDX-License-Identifier: MIT + /** + * Copyright (c) 2022 Hailo Technologies Ltd. All rights reserved. + **/ +--- a/drivers/media/pci/hailo/common/fw_validation.c ++++ b/drivers/media/pci/hailo/common/fw_validation.c +@@ -1,4 +1,4 @@ +-// SPDX-License-Identifier: GPL-2.0 ++// SPDX-License-Identifier: MIT + /** + * Copyright (c) 2019-2022 Hailo Technologies Ltd. All rights reserved. + **/ +@@ -28,16 +28,18 @@ int FW_VALIDATION__validate_fw_header(ui + firmware_header_t *firmware_header = NULL; + u32 consumed_firmware_offset = *outer_consumed_firmware_offset; + u32 expected_firmware_magic = 0; +- ++ + firmware_header = (firmware_header_t *) (firmware_base_address + consumed_firmware_offset); + CONSUME_FIRMWARE(sizeof(firmware_header_t), -EINVAL); + + switch (board_type) { + case HAILO_BOARD_TYPE_HAILO8: +- expected_firmware_magic = FIRMWARE_HEADER_MAGIC_HAILO8; ++ expected_firmware_magic = FIRMWARE_HEADER_MAGIC_HAILO8; + break; ++ case HAILO_BOARD_TYPE_HAILO10H_LEGACY: + case HAILO_BOARD_TYPE_HAILO15: +- expected_firmware_magic = FIRMWARE_HEADER_MAGIC_HAILO15; ++ case HAILO_BOARD_TYPE_HAILO10H: ++ expected_firmware_magic = FIRMWARE_HEADER_MAGIC_HAILO15; + break; + case HAILO_BOARD_TYPE_PLUTO: + expected_firmware_magic = FIRMWARE_HEADER_MAGIC_PLUTO; +--- a/drivers/media/pci/hailo/common/fw_validation.h ++++ b/drivers/media/pci/hailo/common/fw_validation.h +@@ -1,4 +1,4 @@ +-// SPDX-License-Identifier: GPL-2.0 ++// SPDX-License-Identifier: MIT + /** + * Copyright (c) 2019-2022 Hailo Technologies Ltd. All rights reserved. + **/ +@@ -11,8 +11,7 @@ + + #define FIRMWARE_HEADER_MAGIC_HAILO8 (0x1DD89DE0) + #define FIRMWARE_HEADER_MAGIC_HAILO15 (0xE905DAAB) +-// TODO - HRT-11344 : change fw magic to pluto specific +-#define FIRMWARE_HEADER_MAGIC_PLUTO (0xE905DAAB) ++#define FIRMWARE_HEADER_MAGIC_PLUTO (0xF94739AB) + + #ifndef HAILO_EMULATOR + #define FIRMWARE_WAIT_TIMEOUT_MS (5000) +--- a/drivers/media/pci/hailo/common/hailo_ioctl_common.h ++++ b/drivers/media/pci/hailo/common/hailo_ioctl_common.h +@@ -6,6 +6,14 @@ + #ifndef _HAILO_IOCTL_COMMON_H_ + #define _HAILO_IOCTL_COMMON_H_ + ++#define HAILO_DRV_VER_MAJOR 4 ++#define HAILO_DRV_VER_MINOR 18 ++#define HAILO_DRV_VER_REVISION 0 ++ ++#define _STRINGIFY_EXPANDED( x ) #x ++#define _STRINGIFY_NUMBER( x ) _STRINGIFY_EXPANDED(x) ++#define HAILO_DRV_VER _STRINGIFY_NUMBER(HAILO_DRV_VER_MAJOR) "." _STRINGIFY_NUMBER(HAILO_DRV_VER_MINOR) "." _STRINGIFY_NUMBER(HAILO_DRV_VER_REVISION) ++ + + // This value is not easily changeable. + // For example: the channel interrupts ioctls assume we have up to 32 channels +@@ -23,14 +31,17 @@ + #define INVALID_DRIVER_HANDLE_VALUE ((uintptr_t)-1) + + // Used by windows and unix driver to raise the right CPU control handle to the FW. The same as in pcie_service FW +-#define FW_ACCESS_CORE_CPU_CONTROL_SHIFT (1) +-#define FW_ACCESS_CORE_CPU_CONTROL_MASK (1 << FW_ACCESS_CORE_CPU_CONTROL_SHIFT) +-#define FW_ACCESS_CONTROL_INTERRUPT_SHIFT (0) +-#define FW_ACCESS_APP_CPU_CONTROL_MASK (1 << FW_ACCESS_CONTROL_INTERRUPT_SHIFT) +-#define FW_ACCESS_DRIVER_SHUTDOWN_SHIFT (2) +-#define FW_ACCESS_DRIVER_SHUTDOWN_MASK (1 << FW_ACCESS_DRIVER_SHUTDOWN_SHIFT) ++#define FW_ACCESS_CORE_CPU_CONTROL_SHIFT (1) ++#define FW_ACCESS_CORE_CPU_CONTROL_MASK (1 << FW_ACCESS_CORE_CPU_CONTROL_SHIFT) ++#define FW_ACCESS_CONTROL_INTERRUPT_SHIFT (0) ++#define FW_ACCESS_APP_CPU_CONTROL_MASK (1 << FW_ACCESS_CONTROL_INTERRUPT_SHIFT) ++#define FW_ACCESS_DRIVER_SHUTDOWN_SHIFT (2) ++#define FW_ACCESS_DRIVER_SHUTDOWN_MASK (1 << FW_ACCESS_DRIVER_SHUTDOWN_SHIFT) ++#define FW_ACCESS_SOC_CONNECT_SHIFT (3) ++#define FW_ACCESS_SOC_CONNECT_MASK (1 << FW_ACCESS_SOC_CONNECT_SHIFT) ++ ++#define INVALID_VDMA_CHANNEL (0xff) + +-#define INVALID_VDMA_CHANNEL (0xff) + + #if !defined(__cplusplus) && defined(NTDDI_VERSION) + #include +@@ -53,14 +64,23 @@ typedef uint8_t bool; + #define INT_MAX 0x7FFFFFFF + #endif // !defined(INT_MAX) + ++#if !defined(ECONNRESET) ++#define ECONNRESET 104 /* Connection reset by peer */ ++#endif // !defined(ECONNRESET) + + // {d88d31f1-fede-4e71-ac2a-6ce0018c1501} +-DEFINE_GUID (GUID_DEVINTERFACE_HailoKM, ++DEFINE_GUID (GUID_DEVINTERFACE_HailoKM_NNC, + 0xd88d31f1,0xfede,0x4e71,0xac,0x2a,0x6c,0xe0,0x01,0x8c,0x15,0x01); + +-#define HAILO_GENERAL_IOCTL_MAGIC 0 +-#define HAILO_VDMA_IOCTL_MAGIC 1 +-#define HAILO_NON_LINUX_IOCTL_MAGIC 2 ++// {7f16047d-64b8-207a-0092-e970893970a2} ++DEFINE_GUID (GUID_DEVINTERFACE_HailoKM_SOC, ++ 0x7f16047d,0x64b8,0x207a,0x00,0x92,0xe9,0x70,0x89,0x39,0x70,0xa2); ++ ++#define HAILO_GENERAL_IOCTL_MAGIC 0 ++#define HAILO_VDMA_IOCTL_MAGIC 1 ++#define HAILO_SOC_IOCTL_MAGIC 2 ++#define HAILO_PCI_EP_IOCTL_MAGIC 3 ++#define HAILO_NNC_IOCTL_MAGIC 4 + + #define HAILO_IOCTL_COMPATIBLE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS) + +@@ -114,9 +134,11 @@ static ULONG FORCEINLINE _IOC_(ULONG nr, + #define _IOWR_ _IOWR + #define _IO_ _IO + +-#define HAILO_GENERAL_IOCTL_MAGIC 'g' +-#define HAILO_VDMA_IOCTL_MAGIC 'v' +-#define HAILO_NON_LINUX_IOCTL_MAGIC 'w' ++#define HAILO_GENERAL_IOCTL_MAGIC 'g' ++#define HAILO_VDMA_IOCTL_MAGIC 'v' ++#define HAILO_SOC_IOCTL_MAGIC 's' ++#define HAILO_NNC_IOCTL_MAGIC 'n' ++#define HAILO_PCI_EP_IOCTL_MAGIC 'p' + + #elif defined(__QNX__) // #ifdef _MSC_VER + #include +@@ -132,7 +154,6 @@ static ULONG FORCEINLINE _IOC_(ULONG nr, + #define _IO_ __DION + #define HAILO_GENERAL_IOCTL_MAGIC _DCMD_ALL + #define HAILO_VDMA_IOCTL_MAGIC _DCMD_MISC +-#define HAILO_NON_LINUX_IOCTL_MAGIC _DCMD_PROC + + #else // #ifdef _MSC_VER + #error "unsupported platform!" +@@ -161,6 +182,16 @@ enum hailo_dma_data_direction { + HAILO_DMA_MAX_ENUM = INT_MAX, + }; + ++// Enum that states what type of buffer we are working with in the driver ++// TODO: HRT-13580 - Add specific type for user allocated and for driver allocated ++enum hailo_dma_buffer_type { ++ HAILO_DMA_USER_PTR_BUFFER = 0, ++ HAILO_DMA_DMABUF_BUFFER = 1, ++ ++ /** Max enum value to maintain ABI Integrity */ ++ HAILO_DMA_BUFFER_MAX_ENUM = INT_MAX, ++}; ++ + // Enum that determines if buffer should be allocated from user space or from driver + enum hailo_allocation_mode { + HAILO_ALLOCATION_MODE_USERSPACE = 0, +@@ -170,10 +201,19 @@ enum hailo_allocation_mode { + HAILO_ALLOCATION_MODE_MAX_ENUM = INT_MAX, + }; + ++enum hailo_vdma_interrupts_domain { ++ HAILO_VDMA_INTERRUPTS_DOMAIN_NONE = 0, ++ HAILO_VDMA_INTERRUPTS_DOMAIN_DEVICE = (1 << 0), ++ HAILO_VDMA_INTERRUPTS_DOMAIN_HOST = (1 << 1), ++ ++ /** Max enum value to maintain ABI Integrity */ ++ HAILO_VDMA_INTERRUPTS_DOMAIN_MAX_ENUM = INT_MAX, ++}; ++ + /* structure used in ioctl HAILO_VDMA_BUFFER_MAP */ + struct hailo_vdma_buffer_map_params { + #if defined(__linux__) || defined(_MSC_VER) +- void* user_address; // in ++ uintptr_t user_address; // in + #elif defined(__QNX__) + shm_handle_t shared_memory_handle; // in + #else +@@ -181,6 +221,7 @@ struct hailo_vdma_buffer_map_params { + #endif // __linux__ + size_t size; // in + enum hailo_dma_data_direction data_direction; // in ++ enum hailo_dma_buffer_type buffer_type; // in + uintptr_t allocated_buffer_handle; // in + size_t mapped_handle; // out + }; +@@ -204,31 +245,27 @@ struct hailo_desc_list_release_params { + uintptr_t desc_handle; // in + }; + +-/* structure used in ioctl HAILO_NON_LINUX_DESC_LIST_MMAP */ +-struct hailo_non_linux_desc_list_mmap_params { +- uintptr_t desc_handle; // in +- size_t size; // in +- void* user_address; // out +-}; +- + /* structure used in ioctl HAILO_DESC_LIST_BIND_VDMA_BUFFER */ +-struct hailo_desc_list_bind_vdma_buffer_params { ++struct hailo_desc_list_program_params { + size_t buffer_handle; // in + size_t buffer_size; // in + size_t buffer_offset; // in + uintptr_t desc_handle; // in + uint8_t channel_index; // in + uint32_t starting_desc; // in ++ bool should_bind; // in ++ enum hailo_vdma_interrupts_domain last_interrupts_domain; // in ++ bool is_debug; // in + }; + +-/* structure used in ioctl HAILO_VDMA_INTERRUPTS_ENABLE */ +-struct hailo_vdma_interrupts_enable_params { ++/* structure used in ioctl HAILO_VDMA_ENABLE_CHANNELS */ ++struct hailo_vdma_enable_channels_params { + uint32_t channels_bitmap_per_engine[MAX_VDMA_ENGINES]; // in + bool enable_timestamps_measure; // in + }; + +-/* structure used in ioctl HAILO_VDMA_INTERRUPTS_DISABLE */ +-struct hailo_vdma_interrupts_disable_params { ++/* structure used in ioctl HAILO_VDMA_DISABLE_CHANNELS */ ++struct hailo_vdma_disable_channels_params { + uint32_t channels_bitmap_per_engine[MAX_VDMA_ENGINES]; // in + }; + +@@ -237,7 +274,7 @@ struct hailo_vdma_interrupts_channel_dat + uint8_t engine_index; + uint8_t channel_index; + bool is_active; // If not activate, num_processed is ignored. +- uint16_t host_num_processed; ++ uint8_t transfers_completed; // Number of transfers completed. + uint8_t host_error; // Channel errors bits on source side + uint8_t device_error; // Channel errors bits on dest side + bool validation_success; // If the validation of the channel was successful +@@ -312,6 +349,10 @@ enum hailo_transfer_memory_type { + HAILO_TRANSFER_MEMORY_DMA_ENGINE1, + HAILO_TRANSFER_MEMORY_DMA_ENGINE2, + ++ // PCIe EP driver memories ++ HAILO_TRANSFER_MEMORY_PCIE_EP_CONFIG = 0x400, ++ HAILO_TRANSFER_MEMORY_PCIE_EP_BRIDGE, ++ + /** Max enum value to maintain ABI Integrity */ + HAILO_TRANSFER_MEMORY_MAX_ENUM = INT_MAX, + }; +@@ -352,15 +393,26 @@ enum hailo_board_type { + HAILO_BOARD_TYPE_HAILO8 = 0, + HAILO_BOARD_TYPE_HAILO15, + HAILO_BOARD_TYPE_PLUTO, ++ HAILO_BOARD_TYPE_HAILO10H, ++ HAILO_BOARD_TYPE_HAILO10H_LEGACY, + HAILO_BOARD_TYPE_COUNT, + + /** Max enum value to maintain ABI Integrity */ + HAILO_BOARD_TYPE_MAX_ENUM = INT_MAX + }; + ++enum hailo_accelerator_type { ++ HAILO_ACCELERATOR_TYPE_NNC, ++ HAILO_ACCELERATOR_TYPE_SOC, ++ ++ /** Max enum value to maintain ABI Integrity */ ++ HAILO_ACCELERATOR_TYPE_MAX_ENUM = INT_MAX ++}; ++ + enum hailo_dma_type { + HAILO_DMA_TYPE_PCIE, + HAILO_DMA_TYPE_DRAM, ++ HAILO_DMA_TYPE_PCI_EP, + + /** Max enum value to maintain ABI Integrity */ + HAILO_DMA_TYPE_MAX_ENUM = INT_MAX, +@@ -428,15 +480,6 @@ struct hailo_vdma_transfer_buffer { + uint32_t size; // in + }; + +-enum hailo_vdma_interrupts_domain { +- HAILO_VDMA_INTERRUPTS_DOMAIN_NONE = 0, +- HAILO_VDMA_INTERRUPTS_DOMAIN_DEVICE = (1 << 0), +- HAILO_VDMA_INTERRUPTS_DOMAIN_HOST = (1 << 1), +- +- /** Max enum value to maintain ABI Integrity */ +- HAILO_VDMA_INTERRUPTS_DOMAIN_MAX_ENUM = INT_MAX, +-}; +- + // We allow maximum 2 buffers per transfer since we may have an extra buffer + // to make sure each buffer is aligned to page size. + #define HAILO_MAX_BUFFERS_PER_SINGLE_TRANSFER (2) +@@ -460,6 +503,35 @@ struct hailo_vdma_launch_transfer_params + // more info (e.g desc complete status) + + uint32_t descs_programed; // out, amount of descriptors programed. ++ int launch_transfer_status; // out, status of the launch transfer call. (only used in case of error) ++}; ++ ++/* structure used in ioctl HAILO_SOC_CONNECT */ ++struct hailo_soc_connect_params { ++ uint8_t input_channel_index; // out ++ uint8_t output_channel_index; // out ++ uintptr_t input_desc_handle; // in ++ uintptr_t output_desc_handle; // in ++}; ++ ++/* structure used in ioctl HAILO_SOC_CLOSE */ ++struct hailo_soc_close_params { ++ uint8_t input_channel_index; // in ++ uint8_t output_channel_index; // in ++}; ++ ++/* structure used in ioctl HAILO_PCI_EP_ACCEPT */ ++struct hailo_pci_ep_accept_params { ++ uint8_t input_channel_index; // out ++ uint8_t output_channel_index; // out ++ uintptr_t input_desc_handle; // in ++ uintptr_t output_desc_handle; // in ++}; ++ ++/* structure used in ioctl HAILO_PCI_EP_CLOSE */ ++struct hailo_pci_ep_close_params { ++ uint8_t input_channel_index; // in ++ uint8_t output_channel_index; // in + }; + + #ifdef _MSC_VER +@@ -469,8 +541,8 @@ struct tCompatibleHailoIoctlData + ULONG_PTR Value; + union { + struct hailo_memory_transfer_params MemoryTransfer; +- struct hailo_vdma_interrupts_enable_params VdmaInterruptsEnable; +- struct hailo_vdma_interrupts_disable_params VdmaInterruptsDisable; ++ struct hailo_vdma_enable_channels_params VdmaEnableChannels; ++ struct hailo_vdma_disable_channels_params VdmaDisableChannels; + struct hailo_vdma_interrupts_read_timestamp_params VdmaInterruptsReadTimestamps; + struct hailo_vdma_interrupts_wait_params VdmaInterruptsWait; + struct hailo_vdma_buffer_sync_params VdmaBufferSync; +@@ -479,14 +551,17 @@ struct tCompatibleHailoIoctlData + struct hailo_vdma_buffer_unmap_params VdmaBufferUnmap; + struct hailo_desc_list_create_params DescListCreate; + struct hailo_desc_list_release_params DescListReleaseParam; +- struct hailo_desc_list_bind_vdma_buffer_params DescListBind; ++ struct hailo_desc_list_program_params DescListProgram; + struct hailo_d2h_notification D2HNotification; + struct hailo_device_properties DeviceProperties; + struct hailo_driver_info DriverInfo; +- struct hailo_non_linux_desc_list_mmap_params DescListMmap; + struct hailo_read_log_params ReadLog; + struct hailo_mark_as_in_use_params MarkAsInUse; + struct hailo_vdma_launch_transfer_params LaunchTransfer; ++ struct hailo_soc_connect_params ConnectParams; ++ struct hailo_soc_close_params SocCloseParams; ++ struct hailo_pci_ep_accept_params AcceptParams; ++ struct hailo_pci_ep_close_params PciEpCloseParams; + } Buffer; + }; + #endif // _MSC_VER +@@ -495,30 +570,20 @@ struct tCompatibleHailoIoctlData + + enum hailo_general_ioctl_code { + HAILO_MEMORY_TRANSFER_CODE, +- HAILO_FW_CONTROL_CODE, +- HAILO_READ_NOTIFICATION_CODE, +- HAILO_DISABLE_NOTIFICATION_CODE, + HAILO_QUERY_DEVICE_PROPERTIES_CODE, + HAILO_QUERY_DRIVER_INFO_CODE, +- HAILO_READ_LOG_CODE, +- HAILO_RESET_NN_CORE_CODE, + + // Must be last + HAILO_GENERAL_IOCTL_MAX_NR, + }; + + #define HAILO_MEMORY_TRANSFER _IOWR_(HAILO_GENERAL_IOCTL_MAGIC, HAILO_MEMORY_TRANSFER_CODE, struct hailo_memory_transfer_params) +-#define HAILO_FW_CONTROL _IOWR_(HAILO_GENERAL_IOCTL_MAGIC, HAILO_FW_CONTROL_CODE, struct hailo_fw_control) +-#define HAILO_READ_NOTIFICATION _IOW_(HAILO_GENERAL_IOCTL_MAGIC, HAILO_READ_NOTIFICATION_CODE, struct hailo_d2h_notification) +-#define HAILO_DISABLE_NOTIFICATION _IO_(HAILO_GENERAL_IOCTL_MAGIC, HAILO_DISABLE_NOTIFICATION_CODE) + #define HAILO_QUERY_DEVICE_PROPERTIES _IOW_(HAILO_GENERAL_IOCTL_MAGIC, HAILO_QUERY_DEVICE_PROPERTIES_CODE, struct hailo_device_properties) + #define HAILO_QUERY_DRIVER_INFO _IOW_(HAILO_GENERAL_IOCTL_MAGIC, HAILO_QUERY_DRIVER_INFO_CODE, struct hailo_driver_info) +-#define HAILO_READ_LOG _IOWR_(HAILO_GENERAL_IOCTL_MAGIC, HAILO_READ_LOG_CODE, struct hailo_read_log_params) +-#define HAILO_RESET_NN_CORE _IO_(HAILO_GENERAL_IOCTL_MAGIC, HAILO_RESET_NN_CORE_CODE) + + enum hailo_vdma_ioctl_code { +- HAILO_VDMA_INTERRUPTS_ENABLE_CODE, +- HAILO_VDMA_INTERRUPTS_DISABLE_CODE, ++ HAILO_VDMA_ENABLE_CHANNELS_CODE, ++ HAILO_VDMA_DISABLE_CHANNELS_CODE, + HAILO_VDMA_INTERRUPTS_WAIT_CODE, + HAILO_VDMA_INTERRUPTS_READ_TIMESTAMPS_CODE, + HAILO_VDMA_BUFFER_MAP_CODE, +@@ -526,7 +591,7 @@ enum hailo_vdma_ioctl_code { + HAILO_VDMA_BUFFER_SYNC_CODE, + HAILO_DESC_LIST_CREATE_CODE, + HAILO_DESC_LIST_RELEASE_CODE, +- HAILO_DESC_LIST_BIND_VDMA_BUFFER_CODE, ++ HAILO_DESC_LIST_PROGRAM_CODE, + HAILO_VDMA_LOW_MEMORY_BUFFER_ALLOC_CODE, + HAILO_VDMA_LOW_MEMORY_BUFFER_FREE_CODE, + HAILO_MARK_AS_IN_USE_CODE, +@@ -538,38 +603,67 @@ enum hailo_vdma_ioctl_code { + HAILO_VDMA_IOCTL_MAX_NR, + }; + +-#define HAILO_VDMA_INTERRUPTS_ENABLE _IOR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_INTERRUPTS_ENABLE_CODE, struct hailo_vdma_interrupts_enable_params) +-#define HAILO_VDMA_INTERRUPTS_DISABLE _IOR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_INTERRUPTS_DISABLE_CODE, struct hailo_vdma_interrupts_disable_params) ++#define HAILO_VDMA_ENABLE_CHANNELS _IOR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_ENABLE_CHANNELS_CODE, struct hailo_vdma_enable_channels_params) ++#define HAILO_VDMA_DISABLE_CHANNELS _IOR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_DISABLE_CHANNELS_CODE, struct hailo_vdma_disable_channels_params) + #define HAILO_VDMA_INTERRUPTS_WAIT _IOWR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_INTERRUPTS_WAIT_CODE, struct hailo_vdma_interrupts_wait_params) + #define HAILO_VDMA_INTERRUPTS_READ_TIMESTAMPS _IOWR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_INTERRUPTS_READ_TIMESTAMPS_CODE, struct hailo_vdma_interrupts_read_timestamp_params) + +-#define HAILO_VDMA_BUFFER_MAP _IOWR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_BUFFER_MAP_CODE, struct hailo_vdma_buffer_map_params) +-#define HAILO_VDMA_BUFFER_UNMAP _IOR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_BUFFER_UNMAP_CODE, struct hailo_vdma_buffer_unmap_params) +-#define HAILO_VDMA_BUFFER_SYNC _IOR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_BUFFER_SYNC_CODE, struct hailo_vdma_buffer_sync_params) ++#define HAILO_VDMA_BUFFER_MAP _IOWR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_BUFFER_MAP_CODE, struct hailo_vdma_buffer_map_params) ++#define HAILO_VDMA_BUFFER_UNMAP _IOR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_BUFFER_UNMAP_CODE, struct hailo_vdma_buffer_unmap_params) ++#define HAILO_VDMA_BUFFER_SYNC _IOR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_BUFFER_SYNC_CODE, struct hailo_vdma_buffer_sync_params) ++ ++#define HAILO_DESC_LIST_CREATE _IOWR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_DESC_LIST_CREATE_CODE, struct hailo_desc_list_create_params) ++#define HAILO_DESC_LIST_RELEASE _IOR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_DESC_LIST_RELEASE_CODE, struct hailo_desc_list_release_params) ++#define HAILO_DESC_LIST_PROGRAM _IOR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_DESC_LIST_PROGRAM_CODE, struct hailo_desc_list_program_params) + +-#define HAILO_DESC_LIST_CREATE _IOWR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_DESC_LIST_CREATE_CODE, struct hailo_desc_list_create_params) +-#define HAILO_DESC_LIST_RELEASE _IOR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_DESC_LIST_RELEASE_CODE, struct hailo_desc_list_release_params) +-#define HAILO_DESC_LIST_BIND_VDMA_BUFFER _IOR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_DESC_LIST_BIND_VDMA_BUFFER_CODE, struct hailo_desc_list_bind_vdma_buffer_params) ++#define HAILO_VDMA_LOW_MEMORY_BUFFER_ALLOC _IOWR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_LOW_MEMORY_BUFFER_ALLOC_CODE, struct hailo_allocate_low_memory_buffer_params) ++#define HAILO_VDMA_LOW_MEMORY_BUFFER_FREE _IOR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_LOW_MEMORY_BUFFER_FREE_CODE, struct hailo_free_low_memory_buffer_params) + +-#define HAILO_VDMA_LOW_MEMORY_BUFFER_ALLOC _IOWR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_LOW_MEMORY_BUFFER_ALLOC_CODE, struct hailo_allocate_low_memory_buffer_params) +-#define HAILO_VDMA_LOW_MEMORY_BUFFER_FREE _IOR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_LOW_MEMORY_BUFFER_FREE_CODE, struct hailo_free_low_memory_buffer_params) ++#define HAILO_MARK_AS_IN_USE _IOW_(HAILO_VDMA_IOCTL_MAGIC, HAILO_MARK_AS_IN_USE_CODE, struct hailo_mark_as_in_use_params) + +-#define HAILO_MARK_AS_IN_USE _IOW_(HAILO_VDMA_IOCTL_MAGIC, HAILO_MARK_AS_IN_USE_CODE, struct hailo_mark_as_in_use_params) ++#define HAILO_VDMA_CONTINUOUS_BUFFER_ALLOC _IOWR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_CONTINUOUS_BUFFER_ALLOC_CODE, struct hailo_allocate_continuous_buffer_params) ++#define HAILO_VDMA_CONTINUOUS_BUFFER_FREE _IOR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_CONTINUOUS_BUFFER_FREE_CODE, struct hailo_free_continuous_buffer_params) + +-#define HAILO_VDMA_CONTINUOUS_BUFFER_ALLOC _IOWR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_CONTINUOUS_BUFFER_ALLOC_CODE, struct hailo_allocate_continuous_buffer_params) +-#define HAILO_VDMA_CONTINUOUS_BUFFER_FREE _IOR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_CONTINUOUS_BUFFER_FREE_CODE, struct hailo_free_continuous_buffer_params) ++#define HAILO_VDMA_LAUNCH_TRANSFER _IOWR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_LAUNCH_TRANSFER_CODE, struct hailo_vdma_launch_transfer_params) + +-#define HAILO_VDMA_LAUNCH_TRANSFER _IOWR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_LAUNCH_TRANSFER_CODE, struct hailo_vdma_launch_transfer_params) ++enum hailo_nnc_ioctl_code { ++ HAILO_FW_CONTROL_CODE, ++ HAILO_READ_NOTIFICATION_CODE, ++ HAILO_DISABLE_NOTIFICATION_CODE, ++ HAILO_READ_LOG_CODE, ++ HAILO_RESET_NN_CORE_CODE, + ++ // Must be last ++ HAILO_NNC_IOCTL_MAX_NR ++}; + +-enum hailo_non_linux_ioctl_code { +- HAILO_NON_LINUX_DESC_LIST_MMAP_CODE, ++#define HAILO_FW_CONTROL _IOWR_(HAILO_NNC_IOCTL_MAGIC, HAILO_FW_CONTROL_CODE, struct hailo_fw_control) ++#define HAILO_READ_NOTIFICATION _IOW_(HAILO_NNC_IOCTL_MAGIC, HAILO_READ_NOTIFICATION_CODE, struct hailo_d2h_notification) ++#define HAILO_DISABLE_NOTIFICATION _IO_(HAILO_NNC_IOCTL_MAGIC, HAILO_DISABLE_NOTIFICATION_CODE) ++#define HAILO_READ_LOG _IOWR_(HAILO_NNC_IOCTL_MAGIC, HAILO_READ_LOG_CODE, struct hailo_read_log_params) ++#define HAILO_RESET_NN_CORE _IO_(HAILO_NNC_IOCTL_MAGIC, HAILO_RESET_NN_CORE_CODE) ++ ++enum hailo_soc_ioctl_code { ++ HAILO_SOC_IOCTL_CONNECT_CODE, ++ HAILO_SOC_IOCTL_CLOSE_CODE, + + // Must be last +- HAILO_NON_LINUX_IOCTL_MAX_NR, ++ HAILO_SOC_IOCTL_MAX_NR, + }; + +-#define HAILO_NON_LINUX_DESC_LIST_MMAP _IOWR_(HAILO_NON_LINUX_IOCTL_MAGIC, HAILO_NON_LINUX_DESC_LIST_MMAP_CODE, struct hailo_non_linux_desc_list_mmap_params) ++#define HAILO_SOC_CONNECT _IOWR_(HAILO_SOC_IOCTL_MAGIC, HAILO_SOC_IOCTL_CONNECT_CODE, struct hailo_soc_connect_params) ++#define HAILO_SOC_CLOSE _IOR_(HAILO_SOC_IOCTL_MAGIC, HAILO_SOC_IOCTL_CLOSE_CODE, struct hailo_soc_close_params) ++ ++ ++enum hailo_pci_ep_ioctl_code { ++ HAILO_PCI_EP_ACCEPT_CODE, ++ HAILO_PCI_EP_CLOSE_CODE, ++ ++ // Must be last ++ HAILO_PCI_EP_IOCTL_MAX_NR, ++}; + ++#define HAILO_PCI_EP_ACCEPT _IOWR_(HAILO_PCI_EP_IOCTL_MAGIC, HAILO_PCI_EP_ACCEPT_CODE, struct hailo_pci_ep_accept_params) ++#define HAILO_PCI_EP_CLOSE _IOR_(HAILO_PCI_EP_IOCTL_MAGIC, HAILO_PCI_EP_CLOSE_CODE, struct hailo_pci_ep_close_params) + + #endif /* _HAILO_IOCTL_COMMON_H_ */ +--- a/drivers/media/pci/hailo/common/hailo_resource.c ++++ b/drivers/media/pci/hailo/common/hailo_resource.c +@@ -1,4 +1,4 @@ +-// SPDX-License-Identifier: GPL-2.0 ++// SPDX-License-Identifier: MIT + /** + * Copyright (c) 2019-2022 Hailo Technologies Ltd. All rights reserved. + **/ +--- a/drivers/media/pci/hailo/common/hailo_resource.h ++++ b/drivers/media/pci/hailo/common/hailo_resource.h +@@ -1,4 +1,4 @@ +-// SPDX-License-Identifier: GPL-2.0 ++// SPDX-License-Identifier: MIT + /** + * Copyright (c) 2019-2022 Hailo Technologies Ltd. All rights reserved. + **/ +--- a/drivers/media/pci/hailo/common/pcie_common.c ++++ b/drivers/media/pci/hailo/common/pcie_common.c +@@ -1,4 +1,4 @@ +-// SPDX-License-Identifier: GPL-2.0 ++// SPDX-License-Identifier: MIT + /** + * Copyright (c) 2019-2022 Hailo Technologies Ltd. All rights reserved. + **/ +@@ -10,6 +10,8 @@ + #include + #include + #include ++#include ++#include + + + #define BSC_IMASK_HOST (0x0188) +@@ -19,14 +21,13 @@ + + #define PO2_ROUND_UP(size, alignment) ((size + alignment-1) & ~(alignment-1)) + +-#define ATR0_PARAM (0x17) +-#define ATR0_SRC_ADDR (0x0) +-#define ATR0_TRSL_ADDR2 (0x0) +-#define ATR0_TRSL_PARAM (6) ++#define ATR_PARAM (0x17) ++#define ATR_SRC_ADDR (0x0) ++#define ATR_TRSL_PARAM (6) ++#define ATR_TABLE_SIZE (0x1000u) ++#define ATR_TABLE_SIZE_MASK (0x1000u - 1) + + #define ATR0_PCIE_BRIDGE_OFFSET (0x700) +-#define ATR0_TABLE_SIZE (0x1000u) +-#define ATR0_TABLE_SIZE_MASK (0x1000u - 1) + + #define MAXIMUM_APP_FIRMWARE_CODE_SIZE (0x40000) + #define MAXIMUM_CORE_FIRMWARE_CODE_SIZE (0x20000) +@@ -45,8 +46,13 @@ + #define HAILO_PCIE_HOST_DMA_DATA_ID (0) + #define HAILO_PCIE_DMA_DEVICE_INTERRUPTS_BITMASK (1 << 4) + #define HAILO_PCIE_DMA_HOST_INTERRUPTS_BITMASK (1 << 5) ++#define HAILO_PCIE_DMA_SRC_CHANNELS_BITMASK (0x0000FFFF) + +-typedef u32 hailo_ptr_t; ++#define HAILO_PCIE_MAX_ATR_TABLE_INDEX (3) ++ ++#define MAX_FILES_PER_STAGE (4) ++ ++#define BOOT_STATUS_UNINITIALIZED (0x1) + + struct hailo_fw_addresses { + u32 boot_fw_header; +@@ -58,14 +64,11 @@ struct hailo_fw_addresses { + u32 core_fw_header; + u32 atr0_trsl_addr1; + u32 raise_ready_offset; ++ u32 boot_status; + }; + +-struct hailo_atr_config { +- u32 atr_param; +- u32 atr_src; +- u32 atr_trsl_addr_1; +- u32 atr_trsl_addr_2; +- u32 atr_trsl_param; ++struct loading_stage { ++ const struct hailo_file_batch *batch; + }; + + struct hailo_board_compatibility { +@@ -73,6 +76,69 @@ struct hailo_board_compatibility { + const char *fw_filename; + const struct hailo_config_constants board_cfg; + const struct hailo_config_constants fw_cfg; ++ const struct loading_stage stages[MAX_LOADING_STAGES]; ++}; ++ ++static const struct hailo_file_batch hailo10h_files_stg1[] = { ++ { ++ .filename = "hailo/hailo10h/customer_certificate.bin", ++ .address = 0xA0000, ++ .max_size = 0x8004, ++ .is_mandatory = true, ++ .has_header = false ++ }, ++ { ++ .filename = "hailo/hailo10h/u-boot.dtb.signed", ++ .address = 0xA8004, ++ .max_size = 0x20000, ++ .is_mandatory = true, ++ .has_header = false ++ }, ++ { ++ .filename = "hailo/hailo10h/scu_fw.bin", ++ .address = 0x20000, ++ .max_size = 0x40000, ++ .is_mandatory = true, ++ .has_header = true ++ }, ++ { ++ .filename = NULL, ++ .address = 0x00, ++ .max_size = 0x00, ++ .is_mandatory = false, ++ .has_header = false ++ } ++}; ++ ++static const struct hailo_file_batch hailo10h_files_stg2[] = { ++ { ++ .filename = "hailo/hailo10h/u-boot-spl.bin", ++ .address = 0x85000000, ++ .max_size = 0x1000000, ++ .is_mandatory = true, ++ .has_header = false ++ }, ++ { ++ .filename = "hailo/hailo10h/u-boot-tfa.itb", ++ .address = 0x86000000, ++ .max_size = 0x1000000, ++ .is_mandatory = true, ++ .has_header = false ++ }, ++ { ++ .filename = "hailo/hailo10h/fitImage", ++ .address = 0x87000000, ++ .max_size = 0x1000000, ++ .is_mandatory = true, ++ .has_header = false ++ }, ++ { ++ .filename = "hailo/hailo10h/core-image-minimal-hailo10-m2.ext4.gz", ++ .address = 0x88000000, ++ .max_size = 0x20000000, // Max size 512MB ++ .is_mandatory = true, ++ .has_header = false ++ }, + }; + + static const struct hailo_board_compatibility compat[HAILO_BOARD_TYPE_COUNT] = { +@@ -87,6 +153,7 @@ static const struct hailo_board_compatib + .core_fw_header = 0xA0000, + .atr0_trsl_addr1 = 0x60000000, + .raise_ready_offset = 0x1684, ++ .boot_status = 0xe0000, + }, + .fw_filename = "hailo/hailo8_fw.bin", + .board_cfg = { +@@ -100,7 +167,7 @@ static const struct hailo_board_compatib + .max_size = PCIE_HAILO8_FW_CFG_MAX_SIZE, + }, + }, +- [HAILO_BOARD_TYPE_HAILO15] = { ++ [HAILO_BOARD_TYPE_HAILO10H_LEGACY] = { + .fw_addresses = { + .boot_fw_header = 0x88000, + .boot_fw_trigger = 0x88c98, +@@ -111,6 +178,7 @@ static const struct hailo_board_compatib + .core_fw_header = 0xC0000, + .atr0_trsl_addr1 = 0x000BE000, + .raise_ready_offset = 0x1754, ++ .boot_status = 0x80000, + }, + .fw_filename = "hailo/hailo15_fw.bin", + .board_cfg = { +@@ -124,6 +192,39 @@ static const struct hailo_board_compatib + .max_size = 0, + }, + }, ++ [HAILO_BOARD_TYPE_HAILO10H] = { ++ .fw_addresses = { ++ .boot_fw_header = 0x88000, ++ .boot_fw_trigger = 0x88c98, ++ .boot_key_cert = 0x88018, ++ .boot_cont_cert = 0x886a8, ++ .app_fw_code_ram_base = 0x20000, ++ .core_code_ram_base = 0, ++ .core_fw_header = 0, ++ .atr0_trsl_addr1 = 0x000BE000, ++ .raise_ready_offset = 0x1754, ++ .boot_status = 0x80000, ++ }, ++ .fw_filename = NULL, ++ .board_cfg = { ++ .filename = NULL, ++ .address = 0, ++ .max_size = 0, ++ }, ++ .fw_cfg = { ++ .filename = NULL, ++ .address = 0, ++ .max_size = 0, ++ }, ++ .stages = { ++ { ++ .batch = hailo10h_files_stg1, ++ }, ++ { ++ .batch = hailo10h_files_stg2, ++ }, ++ }, ++ }, + // HRT-11344 : none of these matter except raise_ready_offset seeing as we load fw seperately - not through driver + // After implementing bootloader put correct values here + [HAILO_BOARD_TYPE_PLUTO] = { +@@ -138,6 +239,7 @@ static const struct hailo_board_compatib + .atr0_trsl_addr1 = 0x000BE000, + // NOTE: After they update hw consts - check register fw_access_interrupt_w1s of pcie_config + .raise_ready_offset = 0x174c, ++ .boot_status = 0x80000, + }, + .fw_filename = "hailo/pluto_fw.bin", + .board_cfg = { +@@ -225,7 +327,7 @@ int hailo_pcie_read_firmware_control(str + // Copy response buffer + hailo_resource_read_buffer(&resources->fw_access, PCIE_REQUEST_SIZE_OFFSET + (size_t)response_header_size, + command->buffer_len, &command->buffer); +- ++ + return 0; + } + +@@ -253,93 +355,111 @@ int hailo_pcie_read_firmware_notificatio + return hailo_read_firmware_notification(¬ification_resource, notification); + } + +-static void write_atr_table(struct hailo_pcie_resources *resources, +- struct hailo_atr_config *atr) ++int hailo_pcie_configure_atr_table(struct hailo_resource *bridge_config, u64 trsl_addr, u32 atr_index) + { +- hailo_resource_write_buffer(&resources->config, ATR0_PCIE_BRIDGE_OFFSET, +- sizeof(*atr), (void*)atr); +-} ++ size_t offset = 0; ++ struct hailo_atr_config atr = { ++ .atr_param = (ATR_PARAM | (atr_index << 12)), ++ .atr_src = ATR_SRC_ADDR, ++ .atr_trsl_addr_1 = (u32)(trsl_addr & 0xFFFFFFFF), ++ .atr_trsl_addr_2 = (u32)(trsl_addr >> 32), ++ .atr_trsl_param = ATR_TRSL_PARAM ++ }; + +-static void read_atr_table(struct hailo_pcie_resources *resources, +- struct hailo_atr_config *atr) +-{ +- hailo_resource_read_buffer(&resources->config, ATR0_PCIE_BRIDGE_OFFSET, +- sizeof(*atr), (void*)atr); ++ BUG_ON(HAILO_PCIE_MAX_ATR_TABLE_INDEX < atr_index); ++ offset = ATR0_PCIE_BRIDGE_OFFSET + (atr_index * 0x20); ++ ++ return hailo_resource_write_buffer(bridge_config, offset, sizeof(atr), (void*)&atr); + } + +-static void configure_atr_table(struct hailo_pcie_resources *resources, +- hailo_ptr_t base_address) ++void hailo_pcie_read_atr_table(struct hailo_resource *bridge_config, struct hailo_atr_config *atr, u32 atr_index) + { +- struct hailo_atr_config atr = { +- .atr_param = ATR0_PARAM, +- .atr_src = ATR0_SRC_ADDR, +- .atr_trsl_addr_1 = (u32)base_address, +- .atr_trsl_addr_2 = ATR0_TRSL_ADDR2, +- .atr_trsl_param = ATR0_TRSL_PARAM +- }; +- write_atr_table(resources, &atr); ++ size_t offset = 0; ++ ++ BUG_ON(HAILO_PCIE_MAX_ATR_TABLE_INDEX < atr_index); ++ offset = ATR0_PCIE_BRIDGE_OFFSET + (atr_index * 0x20); ++ ++ hailo_resource_read_buffer(bridge_config, offset, sizeof(*atr), (void*)atr); + } + + static void write_memory_chunk(struct hailo_pcie_resources *resources, + hailo_ptr_t dest, u32 dest_offset, const void *src, u32 len) + { ++ u32 ATR_INDEX = 0; + BUG_ON(dest_offset + len > (u32)resources->fw_access.size); + +- configure_atr_table(resources, dest); ++ (void)hailo_pcie_configure_atr_table(&resources->config, (u64)dest, ATR_INDEX); + (void)hailo_resource_write_buffer(&resources->fw_access, dest_offset, len, src); + } + + static void read_memory_chunk( + struct hailo_pcie_resources *resources, hailo_ptr_t src, u32 src_offset, void *dest, u32 len) + { ++ u32 ATR_INDEX = 0; + BUG_ON(src_offset + len > (u32)resources->fw_access.size); + +- configure_atr_table(resources, src); ++ (void)hailo_pcie_configure_atr_table(&resources->config, (u64)src, ATR_INDEX); + (void)hailo_resource_read_buffer(&resources->fw_access, src_offset, len, dest); + } + + // Note: this function modify the device ATR table (that is also used by the firmware for control and vdma). + // Use with caution, and restore the original atr if needed. +-static void write_memory(struct hailo_pcie_resources *resources, hailo_ptr_t dest, const void *src, u32 len) ++void write_memory(struct hailo_pcie_resources *resources, hailo_ptr_t dest, const void *src, u32 len) + { +- hailo_ptr_t base_address = dest & ~ATR0_TABLE_SIZE_MASK; ++ struct hailo_atr_config previous_atr = {0}; ++ hailo_ptr_t base_address = (dest & ~ATR_TABLE_SIZE_MASK); + u32 chunk_len = 0; + u32 offset = 0; ++ u32 ATR_INDEX = 0; ++ ++ // Store previous ATR (Read/write modify the ATR). ++ hailo_pcie_read_atr_table(&resources->config, &previous_atr, ATR_INDEX); + + if (base_address != dest) { + // Data is not aligned, write the first chunk +- chunk_len = min(base_address + ATR0_TABLE_SIZE - dest, len); ++ chunk_len = min(base_address + ATR_TABLE_SIZE - dest, len); + write_memory_chunk(resources, base_address, dest - base_address, src, chunk_len); + offset += chunk_len; + } + + while (offset < len) { +- chunk_len = min(len - offset, ATR0_TABLE_SIZE); ++ chunk_len = min(len - offset, ATR_TABLE_SIZE); + write_memory_chunk(resources, dest + offset, 0, (const u8*)src + offset, chunk_len); + offset += chunk_len; + } ++ ++ (void)hailo_pcie_configure_atr_table(&resources->config, ++ (((u64)(previous_atr.atr_trsl_addr_2) << 32) | previous_atr.atr_trsl_addr_1), ATR_INDEX); + } + + // Note: this function modify the device ATR table (that is also used by the firmware for control and vdma). + // Use with caution, and restore the original atr if needed. + static void read_memory(struct hailo_pcie_resources *resources, hailo_ptr_t src, void *dest, u32 len) + { +- hailo_ptr_t base_address = src & ~ATR0_TABLE_SIZE_MASK; ++ struct hailo_atr_config previous_atr = {0}; ++ hailo_ptr_t base_address = (src & ~ATR_TABLE_SIZE_MASK); + u32 chunk_len = 0; + u32 offset = 0; ++ u32 ATR_INDEX = 0; ++ ++ // Store previous ATR (Read/write modify the ATR). ++ hailo_pcie_read_atr_table(&resources->config, &previous_atr, ATR_INDEX); + + if (base_address != src) { + // Data is not aligned, write the first chunk +- chunk_len = min(base_address + ATR0_TABLE_SIZE - src, len); ++ chunk_len = min(base_address + ATR_TABLE_SIZE - src, len); + read_memory_chunk(resources, base_address, src - base_address, dest, chunk_len); + offset += chunk_len; + } + + while (offset < len) { +- chunk_len = min(len - offset, ATR0_TABLE_SIZE); ++ chunk_len = min(len - offset, ATR_TABLE_SIZE); + read_memory_chunk(resources, src + offset, 0, (u8*)dest + offset, chunk_len); + offset += chunk_len; + } ++ ++ (void)hailo_pcie_configure_atr_table(&resources->config, ++ (((u64)(previous_atr.atr_trsl_addr_2) << 32) | previous_atr.atr_trsl_addr_1), ATR_INDEX); + } + + static void hailo_write_app_firmware(struct hailo_pcie_resources *resources, firmware_header_t *fw_header, +@@ -367,7 +487,7 @@ static void hailo_write_core_firmware(st + write_memory(resources, fw_addresses->core_fw_header, fw_header, sizeof(firmware_header_t)); + } + +-static void hailo_trigger_firmware_boot(struct hailo_pcie_resources *resources) ++void hailo_trigger_firmware_boot(struct hailo_pcie_resources *resources) + { + const struct hailo_fw_addresses *fw_addresses = &(compat[resources->board_type].fw_addresses); + u32 pcie_finished = 1; +@@ -376,6 +496,17 @@ static void hailo_trigger_firmware_boot( + (void*)&pcie_finished, sizeof(pcie_finished)); + } + ++u32 hailo_get_boot_status(struct hailo_pcie_resources *resources) ++{ ++ u32 boot_status = 0; ++ const struct hailo_fw_addresses *fw_addresses = &(compat[resources->board_type].fw_addresses); ++ ++ read_memory(resources, fw_addresses->boot_status, ++ &boot_status, sizeof(boot_status)); ++ ++ return boot_status; ++} ++ + /** + * Validates the FW headers. + * @param[in] address Address of the firmware. +@@ -408,11 +539,14 @@ static int FW_VALIDATION__validate_fw_he + goto exit; + } + +- err = FW_VALIDATION__validate_fw_header(firmware_base_address, firmware_size, MAXIMUM_CORE_FIRMWARE_CODE_SIZE, +- &consumed_firmware_offset, &core_firmware_header, board_type); +- if (0 != err) { +- err = -EINVAL; +- goto exit; ++ // Not validating with HAILO10H since core firmware doesn't loaded over pcie ++ if (HAILO_BOARD_TYPE_HAILO10H != board_type) { ++ err = FW_VALIDATION__validate_fw_header(firmware_base_address, firmware_size, MAXIMUM_CORE_FIRMWARE_CODE_SIZE, ++ &consumed_firmware_offset, &core_firmware_header, board_type); ++ if (0 != err) { ++ err = -EINVAL; ++ goto exit; ++ } + } + + if (consumed_firmware_offset != firmware_size) { +@@ -437,6 +571,70 @@ exit: + return err; + } + ++static int write_single_file(struct hailo_pcie_resources *resources, const struct hailo_file_batch *files_batch, struct device *dev) ++{ ++ const struct firmware *firmware = NULL; ++ firmware_header_t *app_firmware_header = NULL; ++ secure_boot_certificate_t *firmware_cert = NULL; ++ firmware_header_t *core_firmware_header = NULL; ++ int err = 0; ++ ++ err = request_firmware_direct(&firmware, files_batch->filename, dev); ++ if (err < 0) { ++ return err; ++ } ++ ++ if (firmware->size > files_batch->max_size) { ++ release_firmware(firmware); ++ return -EFBIG; ++ } ++ ++ if (files_batch->has_header) { ++ err = FW_VALIDATION__validate_fw_headers((uintptr_t)firmware->data, firmware->size, ++ &app_firmware_header, &core_firmware_header, &firmware_cert, resources->board_type); ++ if (err < 0) { ++ release_firmware(firmware); ++ return err; ++ } ++ ++ hailo_write_app_firmware(resources, app_firmware_header, firmware_cert); ++ } else { ++ write_memory(resources, files_batch->address, (void*)firmware->data, firmware->size); ++ } ++ ++ release_firmware(firmware); ++ ++ return 0; ++} ++ ++int hailo_pcie_write_firmware_batch(struct device *dev, struct hailo_pcie_resources *resources, u32 stage) ++{ ++ const struct hailo_file_batch *files_batch = compat[resources->board_type].stages[stage].batch; ++ int file_index = 0; ++ int err = 0; ++ ++ for (file_index = 0; file_index < MAX_FILES_PER_STAGE; file_index++) ++ { ++ if (NULL == files_batch[file_index].filename) { ++ break; ++ } ++ ++ dev_notice(dev, "Writing file %s\n", files_batch[file_index].filename); ++ ++ err = write_single_file(resources, &files_batch[file_index], dev); ++ if (err < 0) { ++ pr_warn("Failed to write file %s\n", files_batch[file_index].filename); ++ if (files_batch[file_index].is_mandatory) { ++ return err; ++ } ++ } ++ ++ dev_notice(dev, "File %s written successfully\n", files_batch[file_index].filename); ++ } ++ ++ return 0; ++} ++ + int hailo_pcie_write_firmware(struct hailo_pcie_resources *resources, const void *fw_data, size_t fw_size) + { + firmware_header_t *app_firmware_header = NULL; +@@ -457,10 +655,25 @@ int hailo_pcie_write_firmware(struct hai + return 0; + } + ++// TODO: HRT-14147 - remove this function ++bool hailo_pcie_is_device_ready_for_boot(struct hailo_pcie_resources *resources) ++{ ++ return hailo_get_boot_status(resources) == BOOT_STATUS_UNINITIALIZED; ++} ++ + bool hailo_pcie_is_firmware_loaded(struct hailo_pcie_resources *resources) + { +- u32 offset = ATR0_PCIE_BRIDGE_OFFSET + offsetof(struct hailo_atr_config, atr_trsl_addr_1); +- u32 atr_value = hailo_resource_read32(&resources->config, offset); ++ u32 offset; ++ u32 atr_value; ++ ++ // TODO: HRT-14147 ++ if (HAILO_BOARD_TYPE_HAILO10H == resources->board_type) { ++ return !hailo_pcie_is_device_ready_for_boot(resources); ++ } ++ ++ offset = ATR0_PCIE_BRIDGE_OFFSET + offsetof(struct hailo_atr_config, atr_trsl_addr_1); ++ atr_value = hailo_resource_read32(&resources->config, offset); ++ + return atr_value == compat[resources->board_type].fw_addresses.atr0_trsl_addr1; + } + +@@ -516,7 +729,7 @@ void hailo_pcie_update_channel_interrupt + for (i = 0; i < MAX_VDMA_CHANNELS_PER_ENGINE; ++i) { + if (hailo_test_bit(i, &channels_bitmap)) { + // based on 18.5.2 "vDMA Interrupt Registers" in PLDA documentation +- u32 offset = (i < VDMA_DEST_CHANNELS_START) ? 0 : 8; ++ u32 offset = (i & 16) ? 8 : 0; + hailo_set_bit((((int)i*8) / MAX_VDMA_CHANNELS_PER_ENGINE) + offset, &mask); + } + } +@@ -531,7 +744,8 @@ void hailo_pcie_enable_interrupts(struct + hailo_resource_write32(&resources->config, BCS_DESTINATION_INTERRUPT_PER_CHANNEL, 0xFFFFFFFF); + hailo_resource_write32(&resources->config, BCS_SOURCE_INTERRUPT_PER_CHANNEL, 0xFFFFFFFF); + +- mask |= BCS_ISTATUS_HOST_FW_IRQ_CONTROL_MASK | BCS_ISTATUS_HOST_FW_IRQ_NOTIFICATION | BCS_ISTATUS_HOST_DRIVER_DOWN; ++ mask |= (BCS_ISTATUS_HOST_FW_IRQ_CONTROL_MASK | BCS_ISTATUS_HOST_FW_IRQ_NOTIFICATION | ++ BCS_ISTATUS_HOST_DRIVER_DOWN | BCS_ISTATUS_SOC_CONNECT_ACCEPTED); + hailo_resource_write32(&resources->config, BSC_IMASK_HOST, mask); + } + +@@ -569,16 +783,10 @@ long hailo_pcie_read_firmware_log(struct + static int direct_memory_transfer(struct hailo_pcie_resources *resources, + struct hailo_memory_transfer_params *params) + { +- int err = -EINVAL; +- struct hailo_atr_config previous_atr = {0}; +- + if (params->address > U32_MAX) { + return -EFAULT; + } + +- // Store previous ATR (Read/write modify the ATR). +- read_atr_table(resources, &previous_atr); +- + switch (params->transfer_direction) { + case TRANSFER_READ: + read_memory(resources, (u32)params->address, params->buffer, (u32)params->count); +@@ -587,14 +795,10 @@ static int direct_memory_transfer(struct + write_memory(resources, (u32)params->address, params->buffer, (u32)params->count); + break; + default: +- err = -EINVAL; +- goto restore_atr; ++ return -EINVAL; + } + +- err = 0; +-restore_atr: +- write_atr_table(resources, &previous_atr); +- return err; ++ return 0; + } + + int hailo_pcie_memory_transfer(struct hailo_pcie_resources *resources, struct hailo_memory_transfer_params *params) +@@ -623,6 +827,24 @@ bool hailo_pcie_is_device_connected(stru + return PCI_VENDOR_ID_HAILO == hailo_resource_read16(&resources->config, PCIE_CONFIG_VENDOR_OFFSET); + } + ++int hailo_set_device_type(struct hailo_pcie_resources *resources) ++{ ++ switch(resources->board_type) { ++ case HAILO_BOARD_TYPE_HAILO8: ++ case HAILO_BOARD_TYPE_HAILO10H_LEGACY: ++ case HAILO_BOARD_TYPE_PLUTO: ++ resources->accelerator_type = HAILO_ACCELERATOR_TYPE_NNC; ++ break; ++ case HAILO_BOARD_TYPE_HAILO10H: ++ resources->accelerator_type = HAILO_ACCELERATOR_TYPE_SOC; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ + // On PCIe, just return the address + static u64 encode_dma_address(dma_addr_t dma_address, u8 channel_id) + { +@@ -637,5 +859,14 @@ struct hailo_vdma_hw hailo_pcie_vdma_hw + .ddr_data_id = HAILO_PCIE_HOST_DMA_DATA_ID, + .device_interrupts_bitmask = HAILO_PCIE_DMA_DEVICE_INTERRUPTS_BITMASK, + .host_interrupts_bitmask = HAILO_PCIE_DMA_HOST_INTERRUPTS_BITMASK, ++ .src_channels_bitmask = HAILO_PCIE_DMA_SRC_CHANNELS_BITMASK, ++}; + +-}; +\ No newline at end of file ++void hailo_soc_write_soc_connect(struct hailo_pcie_resources *resources) ++{ ++ const struct hailo_fw_addresses *fw_addresses = &(compat[resources->board_type].fw_addresses); ++ const u32 soc_connect_value = FW_ACCESS_SOC_CONNECT_MASK; ++ ++ // Write shutdown flag to FW ++ hailo_resource_write32(&resources->fw_access, fw_addresses->raise_ready_offset, soc_connect_value); ++} +\ No newline at end of file +--- a/drivers/media/pci/hailo/common/pcie_common.h ++++ b/drivers/media/pci/hailo/common/pcie_common.h +@@ -1,4 +1,4 @@ +-// SPDX-License-Identifier: GPL-2.0 ++// SPDX-License-Identifier: MIT + /** + * Copyright (c) 2019-2022 Hailo Technologies Ltd. All rights reserved. + **/ +@@ -14,11 +14,13 @@ + #include "vdma_common.h" + + #include ++#include + + + #define BCS_ISTATUS_HOST_FW_IRQ_CONTROL_MASK (0x04000000) + #define BCS_ISTATUS_HOST_FW_IRQ_NOTIFICATION (0x02000000) + #define BCS_ISTATUS_HOST_DRIVER_DOWN (0x08000000) ++#define BCS_ISTATUS_SOC_CONNECT_ACCEPTED (0x10000000) + #define BCS_ISTATUS_HOST_VDMA_SRC_IRQ_MASK (0x000000FF) + #define BCS_ISTATUS_HOST_VDMA_DEST_IRQ_MASK (0x0000FF00) + +@@ -40,17 +42,35 @@ + #define PCI_DEVICE_ID_HAILO_HAILO15 0x45C4 + #define PCI_DEVICE_ID_HAILO_PLUTO 0x43a2 + ++typedef u32 hailo_ptr_t; ++ + struct hailo_pcie_resources { + struct hailo_resource config; // BAR0 + struct hailo_resource vdma_registers; // BAR2 + struct hailo_resource fw_access; // BAR4 + enum hailo_board_type board_type; ++ enum hailo_accelerator_type accelerator_type; ++}; ++ ++struct hailo_atr_config { ++ u32 atr_param; ++ u32 atr_src; ++ u32 atr_trsl_addr_1; ++ u32 atr_trsl_addr_2; ++ u32 atr_trsl_param; ++}; ++ ++enum loading_stages { ++ FIRST_STAGE = 0, ++ SECOND_STAGE = 1, ++ MAX_LOADING_STAGES = 2 + }; + + enum hailo_pcie_interrupt_masks { + FW_CONTROL = BCS_ISTATUS_HOST_FW_IRQ_CONTROL_MASK, + FW_NOTIFICATION = BCS_ISTATUS_HOST_FW_IRQ_NOTIFICATION, + DRIVER_DOWN = BCS_ISTATUS_HOST_DRIVER_DOWN, ++ SOC_CONNECT_ACCEPTED = BCS_ISTATUS_SOC_CONNECT_ACCEPTED, + VDMA_SRC_IRQ_MASK = BCS_ISTATUS_HOST_VDMA_SRC_IRQ_MASK, + VDMA_DEST_IRQ_MASK = BCS_ISTATUS_HOST_VDMA_DEST_IRQ_MASK + }; +@@ -66,6 +86,14 @@ struct hailo_config_constants { + size_t max_size; + }; + ++struct hailo_file_batch { ++ const char *filename; ++ u32 address; ++ size_t max_size; ++ bool is_mandatory; ++ bool has_header; ++}; ++ + // TODO: HRT-6144 - Align Windows/Linux to QNX + #ifdef __QNX__ + enum hailo_bar_index { +@@ -103,6 +131,7 @@ int hailo_pcie_write_firmware_control(st + int hailo_pcie_read_firmware_control(struct hailo_pcie_resources *resources, struct hailo_fw_control *command); + + int hailo_pcie_write_firmware(struct hailo_pcie_resources *resources, const void *fw_data, size_t fw_size); ++int hailo_pcie_write_firmware_batch(struct device *dev, struct hailo_pcie_resources *resources, u32 stage); + bool hailo_pcie_is_firmware_loaded(struct hailo_pcie_resources *resources); + bool hailo_pcie_wait_for_firmware(struct hailo_pcie_resources *resources); + +@@ -120,6 +149,17 @@ int hailo_pcie_memory_transfer(struct ha + + bool hailo_pcie_is_device_connected(struct hailo_pcie_resources *resources); + void hailo_pcie_write_firmware_driver_shutdown(struct hailo_pcie_resources *resources); ++void write_memory(struct hailo_pcie_resources *resources, hailo_ptr_t dest, const void *src, u32 len); ++void hailo_trigger_firmware_boot(struct hailo_pcie_resources *resources); ++ ++int hailo_set_device_type(struct hailo_pcie_resources *resources); ++ ++u32 hailo_get_boot_status(struct hailo_pcie_resources *resources); ++ ++int hailo_pcie_configure_atr_table(struct hailo_resource *bridge_config, u64 trsl_addr, u32 atr_index); ++void hailo_pcie_read_atr_table(struct hailo_resource *bridge_config, struct hailo_atr_config *atr, u32 atr_index); ++ ++void hailo_soc_write_soc_connect(struct hailo_pcie_resources *resources); + + #ifdef __cplusplus + } +--- a/drivers/media/pci/hailo/common/utils.h ++++ b/drivers/media/pci/hailo/common/utils.h +@@ -1,4 +1,4 @@ +-// SPDX-License-Identifier: GPL-2.0 ++// SPDX-License-Identifier: MIT + /** + * Copyright (c) 2019-2022 Hailo Technologies Ltd. All rights reserved. + **/ +@@ -11,6 +11,12 @@ + #define hailo_clear_bit(bit, pval) { *(pval) &= ~(1 << bit); } + #define hailo_test_bit(pos,var_addr) ((*var_addr) & (1<<(pos))) + ++#define READ_BITS_AT_OFFSET(amount_bits, offset, initial_value) \ ++ (((initial_value) >> (offset)) & ((1 << (amount_bits)) - 1)) ++#define WRITE_BITS_AT_OFFSET(amount_bits, offset, initial_value, value) \ ++ (((initial_value) & ~(((1 << (amount_bits)) - 1) << (offset))) | \ ++ (((value) & ((1 << (amount_bits)) - 1)) << (offset))) ++ + #ifdef __cplusplus + extern "C" + { +@@ -28,6 +34,22 @@ static inline void hailo_set_bit(int nr, + *p |= mask; + } + ++static inline uint8_t ceil_log2(uint32_t n) ++{ ++ uint8_t result = 0; ++ ++ if (n <= 1) { ++ return 0; ++ } ++ ++ while (n > 1) { ++ result++; ++ n = (n + 1) >> 1; ++ } ++ ++ return result; ++} ++ + #ifndef DIV_ROUND_UP + #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) + #endif +--- a/drivers/media/pci/hailo/common/vdma_common.c ++++ b/drivers/media/pci/hailo/common/vdma_common.c +@@ -1,4 +1,4 @@ +-// SPDX-License-Identifier: GPL-2.0 ++// SPDX-License-Identifier: MIT + /** + * Copyright (c) 2019-2022 Hailo Technologies Ltd. All rights reserved. + **/ +@@ -17,25 +17,37 @@ + + + #define CHANNEL_BASE_OFFSET(channel_index) ((channel_index) << 5) +-#define CHANNEL_HOST_OFFSET(channel_index) CHANNEL_BASE_OFFSET(channel_index) + \ +- (channel_index < VDMA_DEST_CHANNELS_START ? 0 : 0x10) +-#define CHANNEL_DEVICE_OFFSET(channel_index) CHANNEL_BASE_OFFSET(channel_index) + \ +- (channel_index < VDMA_DEST_CHANNELS_START ? 0x10 : 0) + + #define CHANNEL_CONTROL_OFFSET (0x0) ++#define CHANNEL_DEPTH_ID_OFFSET (0x1) + #define CHANNEL_NUM_AVAIL_OFFSET (0x2) + #define CHANNEL_NUM_PROC_OFFSET (0x4) + #define CHANNEL_ERROR_OFFSET (0x8) ++#define CHANNEL_DEST_REGS_OFFSET (0x10) + + #define VDMA_CHANNEL_CONTROL_START (0x1) + #define VDMA_CHANNEL_CONTROL_ABORT (0b00) + #define VDMA_CHANNEL_CONTROL_ABORT_PAUSE (0b10) + #define VDMA_CHANNEL_CONTROL_START_ABORT_PAUSE_RESUME_BITMASK (0x3) + #define VDMA_CHANNEL_CONTROL_START_ABORT_BITMASK (0x1) ++#define VDMA_CHANNEL_CONTROL_MASK (0xFC) ++#define VDMA_CHANNEL_CONTROL_START_RESUME (0b01) ++#define VDMA_CHANNEL_CONTROL_START_PAUSE (0b11) ++#define VDMA_CHANNEL_CONTROL_ABORT (0b00) ++#define VDMA_CHANNEL_CONTROL_ABORT_PAUSE (0b10) ++#define VDMA_CHANNEL_CONTROL_START_ABORT_PAUSE_RESUME_BITMASK (0x3) ++#define VDMA_CHANNEL_DESC_DEPTH_WIDTH (4) ++#define VDMA_CHANNEL_DESC_DEPTH_SHIFT (11) ++#define VDMA_CHANNEL_DATA_ID_SHIFT (8) ++#define VDMA_CHANNEL__MAX_CHECKS_CHANNEL_IS_IDLE (10000) ++#define VDMA_CHANNEL__ADDRESS_L_OFFSET (0x0A) ++#define VDMA_CHANNEL__ALIGNED_ADDRESS_L_OFFSET (0x8) ++#define VDMA_CHANNEL__ADDRESS_H_OFFSET (0x0C) + + #define DESCRIPTOR_PAGE_SIZE_SHIFT (8) + #define DESCRIPTOR_DESC_CONTROL (0x2) + #define DESCRIPTOR_ADDR_L_MASK (0xFFFFFFC0) ++#define DESCRIPTOR_LIST_MAX_DEPTH (16) + + #define DESCRIPTOR_DESC_STATUS_DONE_BIT (0x0) + #define DESCRIPTOR_DESC_STATUS_ERROR_BIT (0x1) +@@ -46,10 +58,14 @@ + #define DESC_REQUEST_IRQ_PROCESSED (1 << 2) + #define DESC_REQUEST_IRQ_ERR (1 << 3) + ++#define VDMA_CHANNEL_NUM_PROCESSED_WIDTH (16) ++#define VDMA_CHANNEL_NUM_PROCESSED_MASK ((1 << VDMA_CHANNEL_NUM_PROCESSED_WIDTH) - 1) ++#define VDMA_CHANNEL_NUM_ONGOING_MASK VDMA_CHANNEL_NUM_PROCESSED_MASK + + #define DWORD_SIZE (4) + #define WORD_SIZE (2) + #define BYTE_SIZE (1) ++#define BITS_IN_BYTE (8) + + #define TIMESTAMPS_CIRC_SPACE(timestamp_list) \ + CIRC_SPACE((timestamp_list).head, (timestamp_list).tail, CHANNEL_IRQ_TIMESTAMPS_SIZE) +@@ -146,18 +162,7 @@ void hailo_vdma_program_descriptor(struc + + static u8 get_channel_id(u8 channel_index) + { +- if (channel_index < VDMA_DEST_CHANNELS_START) { +- // H2D channel +- return channel_index; +- } +- else if ((channel_index >= VDMA_DEST_CHANNELS_START) && +- (channel_index < MAX_VDMA_CHANNELS_PER_ENGINE)) { +- // D2H channel +- return channel_index - VDMA_DEST_CHANNELS_START; +- } +- else { +- return INVALID_VDMA_CHANNEL; +- } ++ return (channel_index < MAX_VDMA_CHANNELS_PER_ENGINE) ? (channel_index & 0xF) : INVALID_VDMA_CHANNEL; + } + + static int program_descriptors_in_chunk( +@@ -198,12 +203,36 @@ static int program_descriptors_in_chunk( + return (int)desc_per_chunk; + } + +-int hailo_vdma_program_descriptors_list( ++static unsigned long get_interrupts_bitmask(struct hailo_vdma_hw *vdma_hw, ++ enum hailo_vdma_interrupts_domain interrupts_domain, bool is_debug) ++{ ++ unsigned long bitmask = 0; ++ ++ if (0 != (HAILO_VDMA_INTERRUPTS_DOMAIN_DEVICE & interrupts_domain)) { ++ bitmask |= vdma_hw->device_interrupts_bitmask; ++ } ++ if (0 != (HAILO_VDMA_INTERRUPTS_DOMAIN_HOST & interrupts_domain)) { ++ bitmask |= vdma_hw->host_interrupts_bitmask; ++ } ++ ++ if (bitmask != 0) { ++ bitmask |= DESC_REQUEST_IRQ_PROCESSED | DESC_REQUEST_IRQ_ERR; ++ if (is_debug) { ++ bitmask |= DESC_STATUS_REQ | DESC_STATUS_REQ_ERR; ++ } ++ } ++ ++ return bitmask; ++} ++ ++static int bind_and_program_descriptors_list( + struct hailo_vdma_hw *vdma_hw, + struct hailo_vdma_descriptors_list *desc_list, + u32 starting_desc, + struct hailo_vdma_mapped_transfer_buffer *buffer, +- u8 channel_index) ++ u8 channel_index, ++ enum hailo_vdma_interrupts_domain last_desc_interrupts, ++ bool is_debug) + { + const u8 channel_id = get_channel_id(channel_index); + int desc_programmed = 0; +@@ -260,9 +289,49 @@ int hailo_vdma_program_descriptors_list( + return -EFAULT; + } + ++ desc_list->desc_list[(starting_desc - 1) % desc_list->desc_count].PageSize_DescControl |= ++ get_interrupts_bitmask(vdma_hw, last_desc_interrupts, is_debug); ++ + return desc_programmed; + } + ++static int program_last_desc( ++ struct hailo_vdma_hw *vdma_hw, ++ struct hailo_vdma_descriptors_list *desc_list, ++ u32 starting_desc, ++ struct hailo_vdma_mapped_transfer_buffer *transfer_buffer, ++ enum hailo_vdma_interrupts_domain last_desc_interrupts, ++ bool is_debug) ++{ ++ u8 control = (u8)(DESCRIPTOR_DESC_CONTROL | get_interrupts_bitmask(vdma_hw, last_desc_interrupts, is_debug)); ++ u32 total_descs = DIV_ROUND_UP(transfer_buffer->size, desc_list->desc_page_size); ++ u32 last_desc = (starting_desc + total_descs - 1) % desc_list->desc_count; ++ u32 last_desc_size = transfer_buffer->size - (total_descs - 1) * desc_list->desc_page_size; ++ ++ // Configure only last descriptor with residue size ++ desc_list->desc_list[last_desc].PageSize_DescControl = (u32) ++ ((last_desc_size << DESCRIPTOR_PAGE_SIZE_SHIFT) + control); ++ return (int)total_descs; ++} ++ ++int hailo_vdma_program_descriptors_list( ++ struct hailo_vdma_hw *vdma_hw, ++ struct hailo_vdma_descriptors_list *desc_list, ++ u32 starting_desc, ++ struct hailo_vdma_mapped_transfer_buffer *buffer, ++ bool should_bind, ++ u8 channel_index, ++ enum hailo_vdma_interrupts_domain last_desc_interrupts, ++ bool is_debug) ++{ ++ return should_bind ? ++ bind_and_program_descriptors_list(vdma_hw, desc_list, starting_desc, ++ buffer, channel_index, last_desc_interrupts, is_debug) : ++ program_last_desc(vdma_hw, desc_list, starting_desc, buffer, ++ last_desc_interrupts, is_debug); ++} ++ ++ + static bool channel_control_reg_is_active(u8 control) + { + return (control & VDMA_CHANNEL_CONTROL_START_ABORT_BITMASK) == VDMA_CHANNEL_CONTROL_START; +@@ -270,12 +339,12 @@ static bool channel_control_reg_is_activ + + static int validate_channel_state(struct hailo_vdma_channel *channel) + { +- const u8 control = ioread8(channel->host_regs + CHANNEL_CONTROL_OFFSET); +- const u16 hw_num_avail = ioread16(channel->host_regs + CHANNEL_NUM_AVAIL_OFFSET); ++ u32 host_regs_value = ioread32(channel->host_regs); ++ const u8 control = READ_BITS_AT_OFFSET(BYTE_SIZE * BITS_IN_BYTE, CHANNEL_CONTROL_OFFSET * BITS_IN_BYTE, host_regs_value); ++ const u16 hw_num_avail = READ_BITS_AT_OFFSET(WORD_SIZE * BITS_IN_BYTE, CHANNEL_NUM_AVAIL_OFFSET * BITS_IN_BYTE, host_regs_value); + + if (!channel_control_reg_is_active(control)) { +- pr_err("Channel %d is not active\n", channel->index); +- return -EBUSY; ++ return -ECONNRESET; + } + + if (hw_num_avail != channel->state.num_avail) { +@@ -287,51 +356,16 @@ static int validate_channel_state(struct + return 0; + } + +-static unsigned long get_interrupts_bitmask(struct hailo_vdma_hw *vdma_hw, +- enum hailo_vdma_interrupts_domain interrupts_domain, bool is_debug) +-{ +- unsigned long bitmask = 0; +- +- if (0 != (HAILO_VDMA_INTERRUPTS_DOMAIN_DEVICE & interrupts_domain)) { +- bitmask |= vdma_hw->device_interrupts_bitmask; +- } +- if (0 != (HAILO_VDMA_INTERRUPTS_DOMAIN_HOST & interrupts_domain)) { +- bitmask |= vdma_hw->host_interrupts_bitmask; +- } +- +- if (bitmask != 0) { +- bitmask |= DESC_REQUEST_IRQ_PROCESSED | DESC_REQUEST_IRQ_ERR; +- if (is_debug) { +- bitmask |= DESC_STATUS_REQ | DESC_STATUS_REQ_ERR; +- } +- } +- +- return bitmask; +-} +- + static void set_num_avail(u8 __iomem *host_regs, u16 num_avail) + { +- iowrite16(num_avail, host_regs + CHANNEL_NUM_AVAIL_OFFSET); ++ u32 host_regs_val = ioread32(host_regs); ++ iowrite32(WRITE_BITS_AT_OFFSET(WORD_SIZE * BITS_IN_BYTE, CHANNEL_NUM_AVAIL_OFFSET * BITS_IN_BYTE, host_regs_val, num_avail), ++ host_regs); + } + + static u16 get_num_proc(u8 __iomem *host_regs) + { +- return ioread16(host_regs + CHANNEL_NUM_PROC_OFFSET); +-} +- +-static int program_last_desc( +- struct hailo_vdma_descriptors_list *desc_list, +- u32 starting_desc, +- struct hailo_vdma_mapped_transfer_buffer *transfer_buffer) +-{ +- u32 total_descs = DIV_ROUND_UP(transfer_buffer->size, desc_list->desc_page_size); +- u32 last_desc = (starting_desc + total_descs - 1) % desc_list->desc_count; +- u32 last_desc_size = transfer_buffer->size - (total_descs - 1) * desc_list->desc_page_size; +- +- // Configure only last descriptor with residue size +- desc_list->desc_list[last_desc].PageSize_DescControl = (u32) +- ((last_desc_size << DESCRIPTOR_PAGE_SIZE_SHIFT) + DESCRIPTOR_DESC_CONTROL); +- return (int)total_descs; ++ return READ_BITS_AT_OFFSET(WORD_SIZE * BITS_IN_BYTE, 0, ioread32(host_regs + CHANNEL_NUM_PROC_OFFSET)); + } + + int hailo_vdma_launch_transfer( +@@ -365,6 +399,11 @@ int hailo_vdma_launch_transfer( + return -EINVAL; + } + ++ ret = validate_channel_state(channel); ++ if (ret < 0) { ++ return ret; ++ } ++ + if (channel->state.num_avail != (u16)starting_desc) { + pr_err("Channel %d state out of sync. num available is %d, expected %d\n", + channel->index, channel->state.num_avail, (u16)starting_desc); +@@ -376,25 +415,17 @@ int hailo_vdma_launch_transfer( + return -EINVAL; + } + +- if (is_debug) { +- ret = validate_channel_state(channel); +- if (ret < 0) { +- return ret; +- } +- } +- + BUILD_BUG_ON_MSG((HAILO_MAX_BUFFERS_PER_SINGLE_TRANSFER + 1) != ARRAY_SIZE(ongoing_transfer.dirty_descs), + "Unexpected amount of dirty descriptors"); + ongoing_transfer.dirty_descs_count = buffers_count + 1; + ongoing_transfer.dirty_descs[0] = (u16)starting_desc; + + for (i = 0; i < buffers_count; i++) { +- ret = should_bind ? +- hailo_vdma_program_descriptors_list(vdma_hw, desc_list, starting_desc, &buffers[i], channel->index) : +- program_last_desc(desc_list, starting_desc, &buffers[i]); +- if (ret < 0) { +- return ret; +- } ++ ret = hailo_vdma_program_descriptors_list(vdma_hw, desc_list, ++ starting_desc, &buffers[i], should_bind, channel->index, ++ (i == (buffers_count - 1) ? last_desc_interrupts : HAILO_VDMA_INTERRUPTS_DOMAIN_NONE), ++ is_debug); ++ + total_descs += ret; + last_desc = (starting_desc + ret - 1) % desc_list->desc_count; + starting_desc = (starting_desc + ret) % desc_list->desc_count; +@@ -406,8 +437,6 @@ int hailo_vdma_launch_transfer( + + desc_list->desc_list[first_desc].PageSize_DescControl |= + get_interrupts_bitmask(vdma_hw, first_interrupts_domain, is_debug); +- desc_list->desc_list[last_desc].PageSize_DescControl |= +- get_interrupts_bitmask(vdma_hw, last_desc_interrupts, is_debug); + + ongoing_transfer.last_desc = (u16)last_desc; + ongoing_transfer.is_debug = is_debug; +@@ -477,8 +506,21 @@ static void channel_state_init(struct ha + state->desc_count_mask = U32_MAX; + } + ++static u8 __iomem *get_channel_regs(u8 __iomem *regs_base, u8 channel_index, bool is_host_side, u32 src_channels_bitmask) ++{ ++ // Check if getting host side regs or device side ++ u8 __iomem *channel_regs_base = regs_base + CHANNEL_BASE_OFFSET(channel_index); ++ if (is_host_side) { ++ return hailo_test_bit(channel_index, &src_channels_bitmask) ? channel_regs_base : ++ (channel_regs_base + CHANNEL_DEST_REGS_OFFSET); ++ } else { ++ return hailo_test_bit(channel_index, &src_channels_bitmask) ? (channel_regs_base + CHANNEL_DEST_REGS_OFFSET) : ++ channel_regs_base; ++ } ++} ++ + void hailo_vdma_engine_init(struct hailo_vdma_engine *engine, u8 engine_index, +- const struct hailo_resource *channel_registers) ++ const struct hailo_resource *channel_registers, u32 src_channels_bitmask) + { + u8 channel_index = 0; + struct hailo_vdma_channel *channel; +@@ -489,8 +531,8 @@ void hailo_vdma_engine_init(struct hailo + + for_each_vdma_channel(engine, channel, channel_index) { + u8 __iomem *regs_base = (u8 __iomem *)channel_registers->address; +- channel->host_regs = regs_base + CHANNEL_HOST_OFFSET(channel_index); +- channel->device_regs = regs_base + CHANNEL_DEVICE_OFFSET(channel_index); ++ channel->host_regs = get_channel_regs(regs_base, channel_index, true, src_channels_bitmask); ++ channel->device_regs = get_channel_regs(regs_base, channel_index, false, src_channels_bitmask); + channel->index = channel_index; + channel->timestamp_measure_enabled = false; + +@@ -502,7 +544,15 @@ void hailo_vdma_engine_init(struct hailo + } + } + +-void hailo_vdma_engine_enable_channel_interrupts(struct hailo_vdma_engine *engine, u32 bitmap, ++/** ++ * Enables the given channels bitmap in the given engine. Allows launching transfer ++ * and reading interrupts from the channels. ++ * ++ * @param engine - dma engine. ++ * @param bitmap - channels bitmap to enable. ++ * @param measure_timestamp - if set, allow interrupts timestamp measure. ++ */ ++void hailo_vdma_engine_enable_channels(struct hailo_vdma_engine *engine, u32 bitmap, + bool measure_timestamp) + { + struct hailo_vdma_channel *channel = NULL; +@@ -518,7 +568,14 @@ void hailo_vdma_engine_enable_channel_in + engine->enabled_channels |= bitmap; + } + +-void hailo_vdma_engine_disable_channel_interrupts(struct hailo_vdma_engine *engine, u32 bitmap) ++/** ++ * Disables the given channels bitmap in the given engine. ++ * ++ * @param engine - dma engine. ++ * @param bitmap - channels bitmap to enable. ++ * @param measure_timestamp - if set, allow interrupts timestamp measure. ++ */ ++void hailo_vdma_engine_disable_channels(struct hailo_vdma_engine *engine, u32 bitmap) + { + struct hailo_vdma_channel *channel = NULL; + u8 channel_index = 0; +@@ -582,11 +639,11 @@ void hailo_vdma_engine_set_channel_inter + } + + static void fill_channel_irq_data(struct hailo_vdma_interrupts_channel_data *irq_data, +- struct hailo_vdma_engine *engine, struct hailo_vdma_channel *channel, u16 num_proc, ++ struct hailo_vdma_engine *engine, struct hailo_vdma_channel *channel, u8 transfers_completed, + bool validation_success) + { +- u8 host_control = ioread8(channel->host_regs + CHANNEL_CONTROL_OFFSET); +- u8 device_control = ioread8(channel->device_regs + CHANNEL_CONTROL_OFFSET); ++ u8 host_control = READ_BITS_AT_OFFSET(BYTE_SIZE * BITS_IN_BYTE, CHANNEL_CONTROL_OFFSET * BITS_IN_BYTE, ioread32(channel->host_regs)); ++ u8 device_control = READ_BITS_AT_OFFSET(BYTE_SIZE * BITS_IN_BYTE, CHANNEL_CONTROL_OFFSET * BITS_IN_BYTE, ioread32(channel->device_regs)); + + irq_data->engine_index = engine->index; + irq_data->channel_index = channel->index; +@@ -594,9 +651,9 @@ static void fill_channel_irq_data(struct + irq_data->is_active = channel_control_reg_is_active(host_control) && + channel_control_reg_is_active(device_control); + +- irq_data->host_num_processed = num_proc; +- irq_data->host_error = ioread8(channel->host_regs + CHANNEL_ERROR_OFFSET); +- irq_data->device_error = ioread8(channel->device_regs + CHANNEL_ERROR_OFFSET); ++ irq_data->transfers_completed = transfers_completed; ++ irq_data->host_error = READ_BITS_AT_OFFSET(BYTE_SIZE * BITS_IN_BYTE, 0, ioread32(channel->host_regs + CHANNEL_ERROR_OFFSET)); ++ irq_data->device_error = READ_BITS_AT_OFFSET(BYTE_SIZE * BITS_IN_BYTE, 0, ioread32(channel->device_regs + CHANNEL_ERROR_OFFSET)); + irq_data->validation_success = validation_success; + } + +@@ -635,7 +692,12 @@ int hailo_vdma_engine_fill_irq_data(stru + bool validation_success = true; + + for_each_vdma_channel(engine, channel, channel_index) { ++ u8 transfers_completed = 0; + u16 hw_num_proc = U16_MAX; ++ ++ BUILD_BUG_ON_MSG(HAILO_VDMA_MAX_ONGOING_TRANSFERS >= U8_MAX, ++ "HAILO_VDMA_MAX_ONGOING_TRANSFERS must be less than U8_MAX to use transfers_completed as u8"); ++ + if (!hailo_test_bit(channel->index, &irq_channels_bitmap)) { + continue; + } +@@ -673,12 +735,143 @@ int hailo_vdma_engine_fill_irq_data(stru + channel->state.num_proc = (u16)((cur_transfer->last_desc + 1) & channel->state.desc_count_mask); + + ongoing_transfer_pop(channel, NULL); ++ transfers_completed++; + } + + fill_channel_irq_data(&irq_data->irq_data[irq_data->channels_count], +- engine, channel, hw_num_proc, validation_success); ++ engine, channel, transfers_completed, validation_success); + irq_data->channels_count++; + } + + return 0; ++} ++ ++// For all these functions - best way to optimize might be to not call the function when need to pause and then abort, ++// Rather read value once and maybe save ++// This function reads and writes the register - should try to make more optimized in future ++static void start_vdma_control_register(u8 __iomem *host_regs) ++{ ++ u32 host_regs_value = ioread32(host_regs); ++ iowrite32(WRITE_BITS_AT_OFFSET(BYTE_SIZE * BITS_IN_BYTE, CHANNEL_CONTROL_OFFSET * BITS_IN_BYTE, host_regs_value, ++ VDMA_CHANNEL_CONTROL_START_RESUME), host_regs); ++} ++ ++static void hailo_vdma_channel_pause(u8 __iomem *host_regs) ++{ ++ u32 host_regs_value = ioread32(host_regs); ++ iowrite32(WRITE_BITS_AT_OFFSET(BYTE_SIZE * BITS_IN_BYTE, CHANNEL_CONTROL_OFFSET * BITS_IN_BYTE, host_regs_value, ++ VDMA_CHANNEL_CONTROL_START_PAUSE), host_regs); ++} ++ ++// This function reads and writes the register - should try to make more optimized in future ++static void hailo_vdma_channel_abort(u8 __iomem *host_regs) ++{ ++ u32 host_regs_value = ioread32(host_regs); ++ iowrite32(WRITE_BITS_AT_OFFSET(BYTE_SIZE * BITS_IN_BYTE, CHANNEL_CONTROL_OFFSET * BITS_IN_BYTE, host_regs_value, ++ VDMA_CHANNEL_CONTROL_ABORT), host_regs); ++} ++ ++int hailo_vdma_start_channel(u8 __iomem *host_regs, uint64_t desc_dma_address, uint8_t desc_depth, ++ uint8_t data_id) ++{ ++ u16 dma_address_l = 0; ++ u32 dma_address_h = 0; ++ u32 desc_depth_data_id = 0; ++ ++ if (((desc_dma_address & 0xFFFF) != 0) || ++ (desc_depth > DESCRIPTOR_LIST_MAX_DEPTH)) { ++ return -EINVAL; ++ } ++ ++ // According to spec, depth 16 is equivalent to depth 0. ++ if (DESCRIPTOR_LIST_MAX_DEPTH == desc_depth) { ++ desc_depth = 0; ++ } ++ ++ // Stop old channel state ++ hailo_vdma_stop_channel(host_regs); ++ ++ // Configure address, depth and id ++ dma_address_l = (uint16_t)((desc_dma_address >> 16) & 0xFFFF); ++ iowrite32(WRITE_BITS_AT_OFFSET(WORD_SIZE * BITS_IN_BYTE, (VDMA_CHANNEL__ADDRESS_L_OFFSET - ++ VDMA_CHANNEL__ALIGNED_ADDRESS_L_OFFSET) * BITS_IN_BYTE, ioread32(host_regs + ++ VDMA_CHANNEL__ALIGNED_ADDRESS_L_OFFSET), dma_address_l), host_regs + VDMA_CHANNEL__ALIGNED_ADDRESS_L_OFFSET); ++ ++ dma_address_h = (uint32_t)(desc_dma_address >> 32); ++ iowrite32(dma_address_h, host_regs + VDMA_CHANNEL__ADDRESS_H_OFFSET); ++ ++ desc_depth_data_id = (uint32_t)(desc_depth << VDMA_CHANNEL_DESC_DEPTH_SHIFT) | ++ (data_id << VDMA_CHANNEL_DATA_ID_SHIFT); ++ iowrite32(desc_depth_data_id, host_regs); ++ ++ start_vdma_control_register(host_regs); ++ ++ return 0; ++} ++ ++static bool hailo_vdma_channel_is_idle(u8 __iomem *host_regs, size_t host_side_max_desc_count) ++{ ++ // Num processed and ongoing are next to each other in the memory. ++ // Reading them both in order to save BAR reads. ++ u32 host_side_num_processed_ongoing = ioread32(host_regs + CHANNEL_NUM_PROC_OFFSET); ++ u16 host_side_num_processed = (host_side_num_processed_ongoing & VDMA_CHANNEL_NUM_PROCESSED_MASK); ++ u16 host_side_num_ongoing = (host_side_num_processed_ongoing >> VDMA_CHANNEL_NUM_PROCESSED_WIDTH) & ++ VDMA_CHANNEL_NUM_ONGOING_MASK; ++ ++ if ((host_side_num_processed % host_side_max_desc_count) == (host_side_num_ongoing % host_side_max_desc_count)) { ++ return true; ++ } ++ ++ return false; ++} ++ ++static int hailo_vdma_wait_until_channel_idle(u8 __iomem *host_regs) ++{ ++ bool is_idle = false; ++ uint32_t check_counter = 0; ++ ++ u8 depth = (uint8_t)(READ_BITS_AT_OFFSET(VDMA_CHANNEL_DESC_DEPTH_WIDTH, VDMA_CHANNEL_DESC_DEPTH_SHIFT, ++ ioread32(host_regs))); ++ size_t host_side_max_desc_count = (size_t)(1 << depth); ++ ++ for (check_counter = 0; check_counter < VDMA_CHANNEL__MAX_CHECKS_CHANNEL_IS_IDLE; check_counter++) { ++ is_idle = hailo_vdma_channel_is_idle(host_regs, host_side_max_desc_count); ++ if (is_idle) { ++ return 0; ++ } ++ } ++ ++ return -ETIMEDOUT; ++} ++ ++void hailo_vdma_stop_channel(u8 __iomem *host_regs) ++{ ++ int err = 0; ++ u8 host_side_channel_regs = READ_BITS_AT_OFFSET(BYTE_SIZE * BITS_IN_BYTE, CHANNEL_CONTROL_OFFSET * BITS_IN_BYTE, ioread32(host_regs)); ++ ++ if ((host_side_channel_regs & VDMA_CHANNEL_CONTROL_START_ABORT_PAUSE_RESUME_BITMASK) == VDMA_CHANNEL_CONTROL_ABORT_PAUSE) { ++ // The channel is aborted (we set the channel to VDMA_CHANNEL_CONTROL_ABORT_PAUSE at the end of this function) ++ return; ++ } ++ ++ // Pause the channel ++ // The channel is paused to allow for "all transfers from fetched descriptors..." to be "...completed" ++ // (from PLDA PCIe refernce manual, "9.2.5 Starting a Channel and Transferring Data") ++ hailo_vdma_channel_pause(host_regs); ++ ++ // Even if channel is stuck and not idle, force abort and return error in the end ++ err = hailo_vdma_wait_until_channel_idle(host_regs); ++ // Success oriented - if error occured print error but still abort channel ++ if (err < 0) { ++ pr_err("Timeout occured while waiting for channel to become idle\n"); ++ } ++ ++ // Abort the channel (even of hailo_vdma_wait_until_channel_idle function fails) ++ hailo_vdma_channel_abort(host_regs); ++} ++ ++bool hailo_check_channel_index(u8 channel_index, u32 src_channels_bitmask, bool is_input_channel) ++{ ++ return is_input_channel ? hailo_test_bit(channel_index, &src_channels_bitmask) : ++ (!hailo_test_bit(channel_index, &src_channels_bitmask)); + } +\ No newline at end of file +--- a/drivers/media/pci/hailo/common/vdma_common.h ++++ b/drivers/media/pci/hailo/common/vdma_common.h +@@ -1,4 +1,4 @@ +-// SPDX-License-Identifier: GPL-2.0 ++// SPDX-License-Identifier: MIT + /** + * Copyright (c) 2019-2022 Hailo Technologies Ltd. All rights reserved. + **/ +@@ -30,8 +30,8 @@ struct hailo_vdma_descriptor { + + struct hailo_vdma_descriptors_list { + struct hailo_vdma_descriptor *desc_list; +- u32 desc_count; // Must be power of 2 if is_circular is set. +- u16 desc_page_size; ++ u32 desc_count; // Must be power of 2 if is_circular is set. ++ u16 desc_page_size; + bool is_circular; + }; + +@@ -127,6 +127,9 @@ struct hailo_vdma_hw { + // Bitmask needed to set on each descriptor to enable interrupts (either host/device). + unsigned long host_interrupts_bitmask; + unsigned long device_interrupts_bitmask; ++ ++ // Bitmask for each vdma hw, which channels are src side by index (on pcie/dram - 0x0000FFFF, pci ep - 0xFFFF0000) ++ u32 src_channels_bitmask; + }; + + #define _for_each_element_array(array, size, element, index) \ +@@ -147,7 +150,11 @@ void hailo_vdma_program_descriptor(struc + * @param starting_desc index of the first descriptor to program. If the list + * is circular, this function may wrap around the list. + * @param buffer buffer to program to the descriptors list. ++ * @param should_bind If false, assumes the buffer was already bound to the ++ * desc list. Used for optimization. + * @param channel_index channel index of the channel attached. ++ * @param last_desc_interrupts - interrupts settings on last descriptor. ++ * @param is_debug program descriptors for debug run. + * + * @return On success - the amount of descriptors programmed, negative value on error. + */ +@@ -156,7 +163,10 @@ int hailo_vdma_program_descriptors_list( + struct hailo_vdma_descriptors_list *desc_list, + u32 starting_desc, + struct hailo_vdma_mapped_transfer_buffer *buffer, +- u8 channel_index); ++ bool should_bind, ++ u8 channel_index, ++ enum hailo_vdma_interrupts_domain last_desc_interrupts, ++ bool is_debug); + + /** + * Launch a transfer on some vdma channel. Includes: +@@ -191,14 +201,12 @@ int hailo_vdma_launch_transfer( + bool is_debug); + + void hailo_vdma_engine_init(struct hailo_vdma_engine *engine, u8 engine_index, +- const struct hailo_resource *channel_registers); ++ const struct hailo_resource *channel_registers, u32 src_channels_bitmask); + +-// enable/disable channels interrupt (does not update interrupts mask because the +-// implementation is different between PCIe and DRAM DMA. To support it we +-// can add some ops struct to the engine). +-void hailo_vdma_engine_enable_channel_interrupts(struct hailo_vdma_engine *engine, u32 bitmap, ++void hailo_vdma_engine_enable_channels(struct hailo_vdma_engine *engine, u32 bitmap, + bool measure_timestamp); +-void hailo_vdma_engine_disable_channel_interrupts(struct hailo_vdma_engine *engine, u32 bitmap); ++ ++void hailo_vdma_engine_disable_channels(struct hailo_vdma_engine *engine, u32 bitmap); + + void hailo_vdma_engine_push_timestamps(struct hailo_vdma_engine *engine, u32 bitmap); + int hailo_vdma_engine_read_timestamps(struct hailo_vdma_engine *engine, +@@ -237,6 +245,12 @@ int hailo_vdma_engine_fill_irq_data(stru + struct hailo_vdma_engine *engine, u32 irq_channels_bitmap, + transfer_done_cb_t transfer_done, void *transfer_done_opaque); + ++int hailo_vdma_start_channel(u8 __iomem *host_regs, uint64_t desc_dma_address, uint8_t desc_depth, uint8_t data_id); ++ ++void hailo_vdma_stop_channel(u8 __iomem *host_regs); ++ ++bool hailo_check_channel_index(u8 channel_index, u32 src_channels_bitmask, bool is_input_channel); ++ + #ifdef __cplusplus + } + #endif +--- a/drivers/media/pci/hailo/src/fops.c ++++ b/drivers/media/pci/hailo/src/fops.c +@@ -19,7 +19,6 @@ + #include + #endif + +-#include "hailo_pcie_version.h" + #include "utils.h" + #include "fops.h" + #include "vdma_common.h" +@@ -27,6 +26,7 @@ + #include "vdma/memory.h" + #include "vdma/ioctl.h" + #include "utils/compact.h" ++#include "pci_soc_ioctl.h" + + + #if LINUX_VERSION_CODE >= KERNEL_VERSION( 4, 13, 0 ) +@@ -210,69 +210,66 @@ l_exit: + + int hailo_pcie_fops_release(struct inode *inode, struct file *filp) + { +- struct hailo_pcie_board *pBoard = (struct hailo_pcie_board *)filp->private_data; ++ struct hailo_pcie_board *board = (struct hailo_pcie_board *)filp->private_data; + struct hailo_file_context *context = NULL; + + u32 major = MAJOR(inode->i_rdev); + u32 minor = MINOR(inode->i_rdev); + +- if (pBoard) { +- hailo_info(pBoard, "(%d: %d-%d): fops_release\n", current->tgid, major, minor); ++ if (board) { ++ hailo_info(board, "(%d: %d-%d): fops_release\n", current->tgid, major, minor); + +- if (down_interruptible(&pBoard->mutex)) { +- hailo_err(pBoard, "fops_release down_interruptible failed"); +- return -ERESTARTSYS; +- } + +- context = find_file_context(pBoard, filp); ++ down(&board->mutex); ++ ++ context = find_file_context(board, filp); + if (NULL == context) { +- hailo_err(pBoard, "Invalid driver state, file context does not exist\n"); +- up(&pBoard->mutex); ++ hailo_err(board, "Invalid driver state, file context does not exist\n"); ++ up(&board->mutex); + return -EINVAL; + } + + if (false == context->is_valid) { + // File context is invalid, but open. It's OK to continue finalize and release it. +- hailo_err(pBoard, "Invalid file context\n"); ++ hailo_err(board, "Invalid file context\n"); + } + +- hailo_pcie_clear_notification_wait_list(pBoard, filp); ++ hailo_pcie_clear_notification_wait_list(board, filp); + +- if (filp == pBoard->vdma.used_by_filp) { +- if (hailo_pcie_driver_down(pBoard)) { +- hailo_err(pBoard, "Failed sending FW shutdown event"); ++ if (filp == board->vdma.used_by_filp) { ++ if (hailo_pcie_driver_down(board)) { ++ hailo_err(board, "Failed sending FW shutdown event"); + } + } + +- hailo_vdma_file_context_finalize(&context->vdma_context, &pBoard->vdma, filp); ++ hailo_vdma_file_context_finalize(&context->vdma_context, &board->vdma, filp); + release_file_context(context); + +- if (atomic_dec_and_test(&pBoard->ref_count)) { ++ if (atomic_dec_and_test(&board->ref_count)) { + // Disable interrupts +- hailo_disable_interrupts(pBoard); ++ hailo_disable_interrupts(board); + + if (power_mode_enabled()) { +- if (pBoard->pDev && pci_set_power_state(pBoard->pDev, PCI_D3hot) < 0) { +- hailo_err(pBoard, "Failed setting power state to D3hot"); ++ if (board->pDev && pci_set_power_state(board->pDev, PCI_D3hot) < 0) { ++ hailo_err(board, "Failed setting power state to D3hot"); + } + } + + // deallocate board if already removed +- if (!pBoard->pDev) { +- hailo_dbg(pBoard, "fops_close, freed board\n"); +- up(&pBoard->mutex); +- kfree(pBoard); +- pBoard = NULL; ++ if (!board->pDev) { ++ hailo_dbg(board, "fops_release, freed board\n"); ++ up(&board->mutex); ++ kfree(board); ++ board = NULL; + } else { +- +- hailo_dbg(pBoard, "fops_close, released resources for board\n"); +- up(&pBoard->mutex); ++ hailo_dbg(board, "fops_release, released resources for board\n"); ++ up(&board->mutex); + } + } else { +- up(&pBoard->mutex); ++ up(&board->mutex); + } + +- hailo_dbg(pBoard, "(%d: %d-%d): fops_close: SUCCESS on /dev/hailo%d\n", current->tgid, ++ hailo_dbg(board, "(%d: %d-%d): fops_release: SUCCESS on /dev/hailo%d\n", current->tgid, + major, minor, minor); + } + +@@ -394,6 +391,10 @@ irqreturn_t hailo_irqhandler(int irq, vo + } + } + ++ if (irq_source.interrupt_bitmask & SOC_CONNECT_ACCEPTED) { ++ complete_all(&board->soc_connect_accepted); ++ } ++ + if (0 != irq_source.vdma_channels_bitmap) { + hailo_vdma_irq_handler(&board->vdma, DEFAULT_VDMA_ENGINE_INDEX, + irq_source.vdma_channels_bitmap); +@@ -602,26 +603,35 @@ static long hailo_query_driver_info(stru + return 0; + } + +-static long hailo_general_ioctl(struct hailo_file_context *context, struct hailo_pcie_board *board, +- unsigned int cmd, unsigned long arg, struct file *filp, bool *should_up_board_mutex) ++static long hailo_general_ioctl(struct hailo_pcie_board *board, unsigned int cmd, unsigned long arg) + { + switch (cmd) { + case HAILO_MEMORY_TRANSFER: + return hailo_memory_transfer_ioctl(board, arg); ++ case HAILO_QUERY_DEVICE_PROPERTIES: ++ return hailo_query_device_properties(board, arg); ++ case HAILO_QUERY_DRIVER_INFO: ++ return hailo_query_driver_info(board, arg); ++ default: ++ hailo_err(board, "Invalid general ioctl code 0x%x (nr: %d)\n", cmd, _IOC_NR(cmd)); ++ return -ENOTTY; ++ } ++} ++ ++static long hailo_nnc_ioctl(struct hailo_pcie_board *board, unsigned int cmd, unsigned long arg, ++ struct file *filp, bool *should_up_board_mutex) ++{ ++ switch (cmd) { + case HAILO_FW_CONTROL: + return hailo_fw_control(board, arg, should_up_board_mutex); + case HAILO_READ_NOTIFICATION: + return hailo_read_notification_ioctl(board, arg, filp, should_up_board_mutex); + case HAILO_DISABLE_NOTIFICATION: + return hailo_disable_notification(board, filp); +- case HAILO_QUERY_DEVICE_PROPERTIES: +- return hailo_query_device_properties(board, arg); +- case HAILO_QUERY_DRIVER_INFO: +- return hailo_query_driver_info(board, arg); + case HAILO_READ_LOG: + return hailo_read_log_ioctl(board, arg); + default: +- hailo_err(board, "Invalid general ioctl code 0x%x (nr: %d)\n", cmd, _IOC_NR(cmd)); ++ hailo_err(board, "Invalid nnc ioctl code 0x%x (nr: %d)\n", cmd, _IOC_NR(cmd)); + return -ENOTTY; + } + } +@@ -673,12 +683,28 @@ long hailo_pcie_fops_unlockedioctl(struc + + switch (_IOC_TYPE(cmd)) { + case HAILO_GENERAL_IOCTL_MAGIC: +- err = hailo_general_ioctl(context, board, cmd, arg, filp, &should_up_board_mutex); ++ err = hailo_general_ioctl(board, cmd, arg); + break; + case HAILO_VDMA_IOCTL_MAGIC: + err = hailo_vdma_ioctl(&context->vdma_context, &board->vdma, cmd, arg, filp, &board->mutex, + &should_up_board_mutex); + break; ++ case HAILO_SOC_IOCTL_MAGIC: ++ if (HAILO_ACCELERATOR_TYPE_SOC != board->pcie_resources.accelerator_type) { ++ hailo_err(board, "Ioctl %d is not supported on this accelerator type\n", _IOC_TYPE(cmd)); ++ err = -EINVAL; ++ } else { ++ err = hailo_soc_ioctl(board, &context->vdma_context, &board->vdma, cmd, arg); ++ } ++ break; ++ case HAILO_NNC_IOCTL_MAGIC: ++ if (HAILO_ACCELERATOR_TYPE_NNC != board->pcie_resources.accelerator_type) { ++ hailo_err(board, "Ioctl %d is not supported on this accelerator type\n", _IOC_TYPE(cmd)); ++ err = -EINVAL; ++ } else { ++ err = hailo_nnc_ioctl(board, cmd, arg, filp, &should_up_board_mutex); ++ } ++ break; + default: + hailo_err(board, "Invalid ioctl type %d\n", _IOC_TYPE(cmd)); + err = -ENOTTY; +--- a/drivers/media/pci/hailo/src/fops.h ++++ b/drivers/media/pci/hailo/src/fops.h +@@ -11,6 +11,7 @@ int hailo_pcie_fops_release(struct inode + long hailo_pcie_fops_unlockedioctl(struct file* filp, unsigned int cmd, unsigned long arg); + int hailo_pcie_fops_mmap(struct file* filp, struct vm_area_struct *vma); + int hailo_pcie_driver_down(struct hailo_pcie_board *board); ++void hailo_pcie_ep_init(struct hailo_pcie_board *board); + + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) + irqreturn_t hailo_irqhandler(int irq, void* dev_id, struct pt_regs *regs); +--- /dev/null ++++ b/drivers/media/pci/hailo/src/pci_soc_ioctl.c +@@ -0,0 +1,155 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/** ++ * Copyright (c) 2019-2024 Hailo Technologies Ltd. All rights reserved. ++ **/ ++#include "pci_soc_ioctl.h" ++ ++#include "utils.h" ++#include "vdma_common.h" ++#include "utils/logs.h" ++#include "vdma/memory.h" ++ ++#define PCI_SOC_VDMA_ENGINE_INDEX (0) ++#define PCI_SOC_WAIT_FOR_CONNECT_TIMEOUT_MS (10000) ++ ++long hailo_soc_ioctl(struct hailo_pcie_board *board, struct hailo_vdma_file_context *context, ++ struct hailo_vdma_controller *controller, unsigned int cmd, unsigned long arg) ++{ ++ switch (cmd) { ++ case HAILO_SOC_CONNECT: ++ return hailo_soc_connect_ioctl(board, context, controller, arg); ++ case HAILO_SOC_CLOSE: ++ return hailo_soc_close_ioctl(board, controller, arg); ++ default: ++ hailo_err(board, "Invalid pcie EP ioctl code 0x%x (nr: %d)\n", cmd, _IOC_NR(cmd)); ++ return -ENOTTY; ++ } ++} ++ ++long hailo_soc_connect_ioctl(struct hailo_pcie_board *board, struct hailo_vdma_file_context *context, ++ struct hailo_vdma_controller *controller, unsigned long arg) ++{ ++ struct hailo_soc_connect_params params; ++ struct hailo_vdma_channel *input_channel = NULL; ++ struct hailo_vdma_channel *output_channel = NULL; ++ struct hailo_vdma_engine *vdma_engine = NULL; ++ struct hailo_descriptors_list_buffer *input_descriptors_buffer = NULL; ++ struct hailo_descriptors_list_buffer *output_descriptors_buffer = NULL; ++ uint8_t depth = 0; ++ int err = 0; ++ long completion_result = 0; ++ ++ if (copy_from_user(¶ms, (void *)arg, sizeof(params))) { ++ hailo_err(board, "copy_from_user fail\n"); ++ return -ENOMEM; ++ } ++ ++ // TODO: have pci_ep choose the channel indexes the soc will use - for now use 0 and 16 ++ params.input_channel_index = 0; ++ params.output_channel_index = 16; ++ ++ reinit_completion(&board->soc_connect_accepted); ++ hailo_soc_write_soc_connect(&board->pcie_resources); ++ ++ // Wait for completion ++ completion_result = wait_for_completion_interruptible_timeout(&board->soc_connect_accepted, ++ msecs_to_jiffies(PCI_SOC_WAIT_FOR_CONNECT_TIMEOUT_MS)); ++ if (0 > completion_result) { ++ if (0 == completion_result) { ++ hailo_err(board, "Timeout waiting for connect to be accepted (timeout_ms=%d)\n", PCI_SOC_WAIT_FOR_CONNECT_TIMEOUT_MS); ++ return -ETIMEDOUT; ++ } else { ++ hailo_info(board, "soc connect failed with err=%ld (process was interrupted or killed)\n", ++ completion_result); ++ return -EINTR; ++ } ++ } ++ ++ vdma_engine = &controller->vdma_engines[PCI_SOC_VDMA_ENGINE_INDEX]; ++ input_channel = &vdma_engine->channels[params.input_channel_index]; ++ output_channel = &vdma_engine->channels[params.output_channel_index]; ++ ++ input_descriptors_buffer = hailo_vdma_find_descriptors_buffer(context, params.input_desc_handle); ++ output_descriptors_buffer = hailo_vdma_find_descriptors_buffer(context, params.output_desc_handle); ++ if (NULL == input_descriptors_buffer || NULL == output_descriptors_buffer) { ++ hailo_dev_err(&board->pDev->dev, "input / output descriptors buffer not found \n"); ++ return -EINVAL; ++ } ++ ++ // Make sure channels that we are accepting are not already enabled ++ if (0 != (vdma_engine->enabled_channels & params.input_channel_index) || ++ 0 != (vdma_engine->enabled_channels & params.output_channel_index)) { ++ hailo_dev_err(&board->pDev->dev, "Trying to accept already enabled channels\n"); ++ return -EINVAL; ++ } ++ ++ if (!is_powerof2((size_t)input_descriptors_buffer->desc_list.desc_count) || ++ !is_powerof2((size_t)output_descriptors_buffer->desc_list.desc_count)) { ++ hailo_dev_err(&board->pDev->dev, "Invalid desc list size\n"); ++ return -EINVAL; ++ } ++ ++ // configure and start input channel ++ depth = ceil_log2(input_descriptors_buffer->desc_list.desc_count); ++ // DMA Direction is only to get channel index - so ++ err = hailo_vdma_start_channel(input_channel->host_regs, input_descriptors_buffer->dma_address, depth, ++ board->vdma.hw->ddr_data_id); ++ if (err < 0) { ++ hailo_dev_err(&board->pDev->dev, "Error starting vdma input channel index %u\n", params.input_channel_index); ++ return -EINVAL; ++ } ++ ++ // configure and start output channel ++ depth = ceil_log2(output_descriptors_buffer->desc_list.desc_count); ++ // DMA Direction is only to get channel index - so ++ err = hailo_vdma_start_channel(output_channel->host_regs, output_descriptors_buffer->dma_address, depth, ++ board->vdma.hw->ddr_data_id); ++ if (err < 0) { ++ hailo_dev_err(&board->pDev->dev, "Error starting vdma output channel index %u\n", params.output_channel_index); ++ // Close input channel ++ hailo_vdma_stop_channel(input_channel->host_regs); ++ return -EINVAL; ++ } ++ ++ if (copy_to_user((void *)arg, ¶ms, sizeof(params))) { ++ hailo_dev_err(&board->pDev->dev, "copy_to_user fail\n"); ++ return -ENOMEM; ++ } ++ ++ return 0; ++} ++ ++long hailo_soc_close_ioctl(struct hailo_pcie_board *board, struct hailo_vdma_controller *controller, unsigned long arg) ++{ ++ struct hailo_soc_close_params params; ++ struct hailo_vdma_channel *input_channel = NULL; ++ struct hailo_vdma_channel *output_channel = NULL; ++ struct hailo_vdma_engine *vdma_engine = NULL; ++ ++ if (copy_from_user(¶ms, (void *)arg, sizeof(params))) { ++ hailo_dev_err(&board->pDev->dev, "copy_from_user fail\n"); ++ return -ENOMEM; ++ } ++ ++ vdma_engine = &controller->vdma_engines[PCI_SOC_VDMA_ENGINE_INDEX]; ++ ++ if (!hailo_check_channel_index(params.input_channel_index, controller->hw->src_channels_bitmask, true)) { ++ hailo_dev_err(&board->pDev->dev, "Invalid input channel index %u\n", params.input_channel_index); ++ return -EINVAL; ++ } ++ ++ if (!hailo_check_channel_index(params.output_channel_index, controller->hw->src_channels_bitmask, false)) { ++ hailo_dev_err(&board->pDev->dev, "Invalid output channel index %u\n", params.output_channel_index); ++ return -EINVAL; ++ } ++ ++ input_channel = &vdma_engine->channels[params.input_channel_index]; ++ output_channel = &vdma_engine->channels[params.output_channel_index]; ++ ++ // Close channels ++ hailo_vdma_stop_channel(input_channel->host_regs); ++ hailo_vdma_stop_channel(output_channel->host_regs); ++ ++ hailo_pcie_write_firmware_driver_shutdown(&board->pcie_resources); ++ return 0; ++} +\ No newline at end of file +--- /dev/null ++++ b/drivers/media/pci/hailo/src/pci_soc_ioctl.h +@@ -0,0 +1,19 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/** ++ * Copyright (c) 2019-2024 Hailo Technologies Ltd. All rights reserved. ++ **/ ++ ++#ifndef _HAILO_PCI_SOC_IOCTL_H_ ++#define _HAILO_PCI_SOC_IOCTL_H_ ++ ++#include "vdma/ioctl.h" ++#include "pcie.h" ++ ++ ++long hailo_soc_ioctl(struct hailo_pcie_board *board, struct hailo_vdma_file_context *context, ++ struct hailo_vdma_controller *controller, unsigned int cmd, unsigned long arg); ++long hailo_soc_connect_ioctl(struct hailo_pcie_board *board, struct hailo_vdma_file_context *context, ++ struct hailo_vdma_controller *controller, unsigned long arg); ++long hailo_soc_close_ioctl(struct hailo_pcie_board *board, struct hailo_vdma_controller *controller, unsigned long arg); ++ ++#endif // _HAILO_PCI_SOC_IOCTL_H_ +\ No newline at end of file +--- a/drivers/media/pci/hailo/src/pcie.c ++++ b/drivers/media/pci/hailo/src/pcie.c +@@ -20,7 +20,6 @@ + + #define KERNEL_CODE 1 + +-#include "hailo_pcie_version.h" + #include "hailo_ioctl_common.h" + #include "pcie.h" + #include "fops.h" +@@ -45,6 +44,7 @@ enum hailo_allocate_driver_buffer_driver + static int force_desc_page_size = 0; + static bool g_is_power_mode_enabled = true; + static int force_allocation_from_driver = HAILO_NO_FORCE_BUFFER; ++static bool force_hailo15_legacy_mode = false; + + #define DEVICE_NODE_NAME "hailo" + static int char_major = 0; +@@ -322,7 +322,7 @@ static int hailo_write_config(struct hai + + static bool wait_for_firmware_completion(struct completion *fw_load_completion) + { +- return (0 != wait_for_completion_timeout(fw_load_completion, FIRMWARE_WAIT_TIMEOUT_MS)); ++ return (0 != wait_for_completion_timeout(fw_load_completion, msecs_to_jiffies(FIRMWARE_WAIT_TIMEOUT_MS))); + } + + static int hailo_load_firmware(struct hailo_pcie_resources *resources, +@@ -330,6 +330,7 @@ static int hailo_load_firmware(struct ha + { + const struct firmware *firmware = NULL; + int err = 0; ++ u32 boot_status = 0; + + if (hailo_pcie_is_firmware_loaded(resources)) { + hailo_dev_warn(dev, "Firmware was already loaded\n"); +@@ -368,7 +369,8 @@ static int hailo_load_firmware(struct ha + release_firmware(firmware); + + if (!wait_for_firmware_completion(fw_load_completion)) { +- hailo_dev_err(dev, "Timeout waiting for firmware..\n"); ++ boot_status = hailo_get_boot_status(resources); ++ hailo_dev_err(dev, "Timeout waiting for firmware file, boot status %u\n", boot_status); + return -ETIMEDOUT; + } + +@@ -376,6 +378,55 @@ static int hailo_load_firmware(struct ha + return 0; + } + ++static int hailo_load_firmware_batch(struct hailo_pcie_resources *resources, ++ struct device *dev, struct completion *fw_load_completion) ++{ ++ u32 boot_status = 0; ++ u32 pcie_finished = 1; ++ int err = 0; ++ ++ if (hailo_pcie_is_firmware_loaded(resources)) { ++ hailo_dev_warn(dev, "Firmware batch was already loaded\n"); ++ return 0; ++ } ++ ++ init_completion(fw_load_completion); ++ ++ err = hailo_pcie_write_firmware_batch(dev, resources, FIRST_STAGE); ++ if (err < 0) { ++ hailo_dev_err(dev, "Failed writing firmware files. err %d\n", err); ++ return err; ++ } ++ ++ hailo_trigger_firmware_boot(resources); ++ ++ if (!wait_for_firmware_completion(fw_load_completion)) { ++ boot_status = hailo_get_boot_status(resources); ++ hailo_dev_err(dev, "Timeout waiting for firmware file, boot status %u\n", boot_status); ++ return -ETIMEDOUT; ++ } ++ reinit_completion(fw_load_completion); ++ ++ err = hailo_pcie_write_firmware_batch(dev, resources, SECOND_STAGE); ++ if (err < 0) { ++ hailo_dev_err(dev, "Failed writing firmware files. err %d\n", err); ++ return err; ++ } ++ ++ // TODO: HRT-13838 - Remove, move address to compat, make write_memory static ++ write_memory(resources, 0x84000000, (void*)&pcie_finished, sizeof(pcie_finished)); ++ ++ if (!wait_for_firmware_completion(fw_load_completion)) { ++ boot_status = hailo_get_boot_status(resources); ++ hailo_dev_err(dev, "Timeout waiting for firmware file, boot status %u\n", boot_status); ++ return -ETIMEDOUT; ++ } ++ ++ hailo_dev_notice(dev, "Firmware Batch loaded successfully\n"); ++ ++ return 0; ++} ++ + static int hailo_activate_board(struct hailo_pcie_board *board) + { + int err = 0; +@@ -388,8 +439,21 @@ static int hailo_activate_board(struct h + return err; + } + +- err = hailo_load_firmware(&board->pcie_resources, &board->pDev->dev, +- &board->fw_loaded_completion); ++ switch (board->pcie_resources.board_type) { ++ case HAILO_BOARD_TYPE_HAILO10H: ++ err = hailo_load_firmware_batch(&board->pcie_resources, &board->pDev->dev, ++ &board->fw_loaded_completion); ++ break; ++ case HAILO_BOARD_TYPE_HAILO10H_LEGACY: ++ case HAILO_BOARD_TYPE_PLUTO: ++ case HAILO_BOARD_TYPE_HAILO8: ++ err = hailo_load_firmware(&board->pcie_resources, &board->pDev->dev, ++ &board->fw_loaded_completion); ++ break; ++ default: ++ hailo_err(board, "Invalid board type"); ++ err = -EINVAL; ++ } + if (err < 0) { + hailo_err(board, "Firmware load failed\n"); + hailo_disable_interrupts(board); +@@ -513,8 +577,23 @@ static int pcie_resources_init(struct pc + goto failure_release_vdma_regs; + } + ++ ++ // There is no HAILO15 as mercury through pcie unless it's legacy mode (H15 as accelerator) or HAILO-10H ++ if (HAILO_BOARD_TYPE_HAILO15 == board_type){ ++ if (true == force_hailo15_legacy_mode) { ++ board_type = HAILO_BOARD_TYPE_HAILO10H_LEGACY; ++ } else { ++ board_type = HAILO_BOARD_TYPE_HAILO10H; ++ } ++ } ++ + resources->board_type = board_type; + ++ err = hailo_set_device_type(resources); ++ if (err < 0) { ++ goto failure_release_fw_access; ++ } ++ + if (!hailo_pcie_is_device_connected(resources)) { + pci_err(pdev, "Probing: Failed reading device BARs, device may be disconnected\n"); + err = -ENODEV; +@@ -676,6 +755,7 @@ static int hailo_pcie_probe(struct pci_d + + pBoard->interrupts_enabled = false; + init_completion(&pBoard->fw_loaded_completion); ++ init_completion(&pBoard->soc_connect_accepted); + + sema_init(&pBoard->mutex, 1); + atomic_set(&pBoard->ref_count, 0); +@@ -1005,6 +1085,9 @@ MODULE_PARM_DESC(force_allocation_from_d + module_param(force_desc_page_size, int, S_IRUGO); + MODULE_PARM_DESC(force_desc_page_size, "Determines the maximum DMA descriptor page size (must be a power of 2)"); + ++module_param(force_hailo15_legacy_mode, bool, S_IRUGO); ++MODULE_PARM_DESC(force_hailo15_legacy_mode, "Forces work with Hailo15 in legacy mode(relevant for emulators)"); ++ + MODULE_AUTHOR("Hailo Technologies Ltd."); + MODULE_DESCRIPTION("Hailo PCIe driver"); + MODULE_LICENSE("GPL v2"); +--- a/drivers/media/pci/hailo/src/pcie.h ++++ b/drivers/media/pci/hailo/src/pcie.h +@@ -70,6 +70,8 @@ struct hailo_pcie_board { + enum hailo_allocation_mode allocation_mode; + struct completion fw_loaded_completion; + bool interrupts_enabled; ++ // Only needed in accelerator type soc ++ struct completion soc_connect_accepted; + }; + + bool power_mode_enabled(void); +--- a/drivers/media/pci/hailo/src/sysfs.c ++++ b/drivers/media/pci/hailo/src/sysfs.c +@@ -26,9 +26,18 @@ static ssize_t device_id_show(struct dev + } + static DEVICE_ATTR_RO(device_id); + ++static ssize_t accelerator_type_show(struct device *dev, struct device_attribute *_attr, ++ char *buf) ++{ ++ struct hailo_pcie_board *board = (struct hailo_pcie_board *)dev_get_drvdata(dev); ++ return sprintf(buf, "%d", board->pcie_resources.accelerator_type); ++} ++static DEVICE_ATTR_RO(accelerator_type); ++ + static struct attribute *hailo_dev_attrs[] = { + &dev_attr_board_location.attr, + &dev_attr_device_id.attr, ++ &dev_attr_accelerator_type.attr, + NULL + }; + +--- a/drivers/media/pci/hailo/src/utils.c ++++ b/drivers/media/pci/hailo/src/utils.c +@@ -8,7 +8,6 @@ + #include + #include + +-#include "hailo_pcie_version.h" + #include "pcie.h" + #include "utils.h" + #include "utils/logs.h" +--- /dev/null ++++ b/drivers/media/pci/hailo/utils/integrated_nnc_utils.c +@@ -0,0 +1,101 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/** ++ * Copyright (c) 2019-2022 Hailo Technologies Ltd. All rights reserved. ++ **/ ++ ++#include "integrated_nnc_utils.h" ++#include "utils/logs.h" ++ ++#include ++#include ++#include ++#include ++ ++int hailo_ioremap_resource(struct platform_device *pdev, struct hailo_resource *resource, ++ const char *name) ++{ ++ void __iomem *address; ++ struct resource *platform_resource = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); ++ if (NULL == platform_resource) { ++ return -ENOENT; ++ } ++ ++ address = devm_ioremap_resource(&pdev->dev, platform_resource); ++ if (IS_ERR(address)) { ++ return PTR_ERR(address); ++ } ++ ++ resource->address = (uintptr_t)address; ++ resource->size = resource_size(platform_resource); ++ ++ hailo_dev_dbg(&pdev->dev, "resource[%s]: remap %pr of %zx bytes to virtual start address %lx\n", ++ platform_resource->name, platform_resource, resource->size, (uintptr_t)address); ++ ++ return 0; ++} ++ ++// TODO: HRT-8475 - change to name instead of index ++int hailo_ioremap_shmem(struct platform_device *pdev, int index, struct hailo_resource *resource) ++{ ++ int ret; ++ struct resource res; ++ struct device_node *shmem; ++ void __iomem * remap_ptr; ++ ++ shmem = of_parse_phandle(pdev->dev.of_node, "shmem", index); ++ ret = of_address_to_resource(shmem, 0, &res); ++ if (ret) { ++ hailo_dev_err(&pdev->dev, "hailo_ioremap_shmem, failed to get memory (index: %d)\n", index); ++ return ret; ++ } ++ of_node_put(shmem); ++ ++ remap_ptr = devm_ioremap(&pdev->dev, res.start, resource_size(&res)); ++ if (!remap_ptr) { ++ hailo_dev_err(&pdev->dev, "hailo_ioremap_shmem, failed to ioremap shmem (index: %d)\n", index); ++ return -EADDRNOTAVAIL; ++ } ++ ++ resource->address = (uintptr_t)remap_ptr; ++ resource->size = resource_size(&res); ++ ++ return 0; ++} ++ ++int direct_memory_transfer(struct platform_device *pdev, struct hailo_memory_transfer_params *params) ++{ ++ int err = -EINVAL; ++ void __iomem *mem = ioremap(params->address, params->count); ++ if (NULL == mem) { ++ hailo_dev_err(&pdev->dev, "Failed ioremap %llu %zu\n", params->address, params->count); ++ return -ENOMEM; ++ } ++ ++ switch (params->transfer_direction) { ++ case TRANSFER_READ: ++ memcpy_fromio(params->buffer, mem, params->count); ++ err = 0; ++ break; ++ case TRANSFER_WRITE: ++ memcpy_toio(mem, params->buffer, params->count); ++ err = 0; ++ break; ++ default: ++ hailo_dev_err(&pdev->dev, "Invalid transfer direction %d\n", (int)params->transfer_direction); ++ err = -EINVAL; ++ } ++ ++ iounmap(mem); ++ return err; ++} ++ ++int hailo_get_resource_physical_addr(struct platform_device *pdev, const char *name, u64 *address) ++{ ++ struct resource *platform_resource = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); ++ if (NULL == platform_resource) { ++ return -ENOENT; ++ } ++ ++ *address = (u64)(platform_resource->start); ++ return 0; ++} +\ No newline at end of file +--- /dev/null ++++ b/drivers/media/pci/hailo/utils/integrated_nnc_utils.h +@@ -0,0 +1,30 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/** ++ * Copyright (c) 2019-2022 Hailo Technologies Ltd. All rights reserved. ++ **/ ++ ++#ifndef _INTEGRATED_NNC_UTILS_H_ ++#define _INTEGRATED_NNC_UTILS_H_ ++ ++#include ++#include "hailo_resource.h" ++ ++#define HAILO15_CORE_CONTROL_MAILBOX_INDEX (0) ++#define HAILO15_CORE_NOTIFICATION_MAILBOX_INDEX (1) ++#define HAILO15_CORE_DRIVER_DOWN_MAILBOX_INDEX (2) ++ ++#define HAILO15_CORE_CONTROL_MAILBOX_TX_SHMEM_INDEX (0) ++#define HAILO15_CORE_CONTROL_MAILBOX_RX_SHMEM_INDEX (1) ++#define HAILO15_CORE_NOTIFICATION_MAILBOX_RX_SHMEM_INDEX (2) ++ ++int hailo_ioremap_resource(struct platform_device *pdev, struct hailo_resource *resource, ++ const char *name); ++ ++// TODO: HRT-8475 - change to name instead of index ++int hailo_ioremap_shmem(struct platform_device *pdev, int index, struct hailo_resource *resource); ++ ++int direct_memory_transfer(struct platform_device *pDev, struct hailo_memory_transfer_params *params); ++ ++int hailo_get_resource_physical_addr(struct platform_device *pdev, const char *name, u64 *address); ++ ++#endif /* _INTEGRATED_NNC_UTILS_H_ */ +--- a/drivers/media/pci/hailo/vdma/ioctl.c ++++ b/drivers/media/pci/hailo/vdma/ioctl.c +@@ -12,9 +12,9 @@ + #include + + +-long hailo_vdma_interrupts_enable_ioctl(struct hailo_vdma_controller *controller, unsigned long arg) ++long hailo_vdma_enable_channels_ioctl(struct hailo_vdma_controller *controller, unsigned long arg) + { +- struct hailo_vdma_interrupts_enable_params input; ++ struct hailo_vdma_enable_channels_params input; + struct hailo_vdma_engine *engine = NULL; + u8 engine_index = 0; + u32 channels_bitmap = 0; +@@ -35,7 +35,7 @@ long hailo_vdma_interrupts_enable_ioctl( + + for_each_vdma_engine(controller, engine, engine_index) { + channels_bitmap = input.channels_bitmap_per_engine[engine_index]; +- hailo_vdma_engine_enable_channel_interrupts(engine, channels_bitmap, ++ hailo_vdma_engine_enable_channels(engine, channels_bitmap, + input.enable_timestamps_measure); + hailo_vdma_update_interrupts_mask(controller, engine_index); + hailo_dev_info(controller->dev, "Enabled interrupts for engine %u, channels bitmap 0x%x\n", +@@ -45,12 +45,13 @@ long hailo_vdma_interrupts_enable_ioctl( + return 0; + } + +-long hailo_vdma_interrupts_disable_ioctl(struct hailo_vdma_controller *controller, unsigned long arg) ++long hailo_vdma_disable_channels_ioctl(struct hailo_vdma_controller *controller, unsigned long arg) + { +- struct hailo_vdma_interrupts_disable_params input; ++ struct hailo_vdma_disable_channels_params input; + struct hailo_vdma_engine *engine = NULL; + u8 engine_index = 0; + u32 channels_bitmap = 0; ++ unsigned long irq_saved_flags = 0; + + if (copy_from_user(&input, (void*)arg, sizeof(input))) { + hailo_dev_err(controller->dev, "copy_from_user fail\n"); +@@ -61,15 +62,21 @@ long hailo_vdma_interrupts_disable_ioctl + for_each_vdma_engine(controller, engine, engine_index) { + channels_bitmap = input.channels_bitmap_per_engine[engine_index]; + if (channels_bitmap != (channels_bitmap & engine->enabled_channels)) { +- hailo_dev_err(controller->dev, "Trying to disable channels that were not enabled\n"); +- return -EINVAL; ++ hailo_dev_warn(controller->dev, "Trying to disable channels that were not enabled\n"); + } + } + + for_each_vdma_engine(controller, engine, engine_index) { + channels_bitmap = input.channels_bitmap_per_engine[engine_index]; +- hailo_vdma_engine_interrupts_disable(controller, engine, engine_index, +- channels_bitmap); ++ hailo_vdma_engine_disable_channels(engine, channels_bitmap); ++ hailo_vdma_update_interrupts_mask(controller, engine_index); ++ ++ spin_lock_irqsave(&controller->interrupts_lock, irq_saved_flags); ++ hailo_vdma_engine_clear_channel_interrupts(engine, channels_bitmap); ++ spin_unlock_irqrestore(&controller->interrupts_lock, irq_saved_flags); ++ ++ hailo_dev_info(controller->dev, "Disabled channels for engine %u, bitmap 0x%x\n", ++ engine_index, channels_bitmap); + } + + // Wake up threads waiting +@@ -197,7 +204,7 @@ long hailo_vdma_buffer_map_ioctl(struct + return -EFAULT; + } + +- hailo_dev_info(controller->dev, "address %px tgid %d size: %zu\n", ++ hailo_dev_info(controller->dev, "address %lx tgid %d size: %zu\n", + buf_info.user_address, current->tgid, buf_info.size); + + direction = get_dma_direction(buf_info.data_direction); +@@ -209,10 +216,9 @@ long hailo_vdma_buffer_map_ioctl(struct + low_memory_buffer = hailo_vdma_find_low_memory_buffer(context, buf_info.allocated_buffer_handle); + + mapped_buffer = hailo_vdma_buffer_map(controller->dev, +- buf_info.user_address, buf_info.size, direction, low_memory_buffer); ++ buf_info.user_address, buf_info.size, direction, buf_info.buffer_type, low_memory_buffer); + if (IS_ERR(mapped_buffer)) { +- hailo_dev_err(controller->dev, "failed map buffer %px\n", +- buf_info.user_address); ++ hailo_dev_err(controller->dev, "failed map buffer %lx\n", buf_info.user_address); + return PTR_ERR(mapped_buffer); + } + +@@ -225,7 +231,7 @@ long hailo_vdma_buffer_map_ioctl(struct + } + + list_add(&mapped_buffer->mapped_user_buffer_list, &context->mapped_user_buffer_list); +- hailo_dev_info(controller->dev, "buffer %px (handle %zu) is mapped\n", ++ hailo_dev_info(controller->dev, "buffer %lx (handle %zu) is mapped\n", + buf_info.user_address, buf_info.mapped_handle); + return 0; + } +@@ -374,10 +380,10 @@ long hailo_desc_list_release_ioctl(struc + return 0; + } + +-long hailo_desc_list_bind_vdma_buffer(struct hailo_vdma_file_context *context, struct hailo_vdma_controller *controller, ++long hailo_desc_list_program_ioctl(struct hailo_vdma_file_context *context, struct hailo_vdma_controller *controller, + unsigned long arg) + { +- struct hailo_desc_list_bind_vdma_buffer_params configure_info; ++ struct hailo_desc_list_program_params configure_info; + struct hailo_vdma_buffer *mapped_buffer = NULL; + struct hailo_descriptors_list_buffer *descriptors_buffer = NULL; + struct hailo_vdma_mapped_transfer_buffer transfer_buffer = {0}; +@@ -410,7 +416,10 @@ long hailo_desc_list_bind_vdma_buffer(st + &descriptors_buffer->desc_list, + configure_info.starting_desc, + &transfer_buffer, +- configure_info.channel_index ++ configure_info.should_bind, ++ configure_info.channel_index, ++ configure_info.last_interrupts_domain, ++ configure_info.is_debug + ); + } + +@@ -683,11 +692,19 @@ long hailo_vdma_launch_transfer_ioctl(st + params.is_debug + ); + if (ret < 0) { +- hailo_dev_err(controller->dev, "Failed launch transfer %d\n", ret); ++ params.launch_transfer_status = ret; ++ if (-ECONNRESET != ret) { ++ hailo_dev_err(controller->dev, "Failed launch transfer %d\n", ret); ++ } ++ // Still need to copy fail status back to userspace - success oriented ++ if (copy_to_user((void __user*)arg, ¶ms, sizeof(params))) { ++ hailo_dev_err(controller->dev, "copy_to_user fail\n"); ++ } + return ret; + } + + params.descs_programed = ret; ++ params.launch_transfer_status = 0; + + if (copy_to_user((void __user*)arg, ¶ms, sizeof(params))) { + hailo_dev_err(controller->dev, "copy_to_user fail\n"); +--- a/drivers/media/pci/hailo/vdma/ioctl.h ++++ b/drivers/media/pci/hailo/vdma/ioctl.h +@@ -8,8 +8,8 @@ + + #include "vdma/vdma.h" + +-long hailo_vdma_interrupts_enable_ioctl(struct hailo_vdma_controller *controller, unsigned long arg); +-long hailo_vdma_interrupts_disable_ioctl(struct hailo_vdma_controller *controller, unsigned long arg); ++long hailo_vdma_enable_channels_ioctl(struct hailo_vdma_controller *controller, unsigned long arg); ++long hailo_vdma_disable_channels_ioctl(struct hailo_vdma_controller *controller, unsigned long arg); + long hailo_vdma_interrupts_wait_ioctl(struct hailo_vdma_controller *controller, unsigned long arg, + struct semaphore *mutex, bool *should_up_board_mutex); + +@@ -19,7 +19,7 @@ long hailo_vdma_buffer_sync_ioctl(struct + + long hailo_desc_list_create_ioctl(struct hailo_vdma_file_context *context, struct hailo_vdma_controller *controller, unsigned long arg); + long hailo_desc_list_release_ioctl(struct hailo_vdma_file_context *context, struct hailo_vdma_controller *controller, unsigned long arg); +-long hailo_desc_list_bind_vdma_buffer(struct hailo_vdma_file_context *context, struct hailo_vdma_controller *controller, unsigned long arg); ++long hailo_desc_list_program_ioctl(struct hailo_vdma_file_context *context, struct hailo_vdma_controller *controller, unsigned long arg); + + long hailo_vdma_low_memory_buffer_alloc_ioctl(struct hailo_vdma_file_context *context, struct hailo_vdma_controller *controller, unsigned long arg); + long hailo_vdma_low_memory_buffer_free_ioctl(struct hailo_vdma_file_context *context, struct hailo_vdma_controller *controller, unsigned long arg); +--- a/drivers/media/pci/hailo/vdma/memory.c ++++ b/drivers/media/pci/hailo/vdma/memory.c +@@ -11,27 +11,107 @@ + #include + #include + #include ++#include + + + #define SGL_MAX_SEGMENT_SIZE (0x10000) + // See linux/mm.h + #define MMIO_AND_NO_PAGES_VMA_MASK (VM_IO | VM_PFNMAP) + +-static int map_mmio_address(void __user* user_address, u32 size, struct vm_area_struct *vma, ++static int map_mmio_address(uintptr_t user_address, u32 size, struct vm_area_struct *vma, + struct sg_table *sgt); +-static int prepare_sg_table(struct sg_table *sg_table, void __user* user_address, u32 size, ++static int prepare_sg_table(struct sg_table *sg_table, uintptr_t user_address, u32 size, + struct hailo_vdma_low_memory_buffer *low_mem_driver_allocated_buffer); + static void clear_sg_table(struct sg_table *sgt); + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION( 3, 3, 0 ) ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0) ++// Import DMA_BUF namespace for needed kernels ++MODULE_IMPORT_NS(DMA_BUF); ++#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0) */ ++ ++static int hailo_map_dmabuf(struct device *dev, int dmabuf_fd, enum dma_data_direction direction, struct sg_table *sgt, ++ struct hailo_dmabuf_info *dmabuf_info) ++{ ++ int ret = -EINVAL; ++ struct dma_buf *dmabuf = NULL; ++ struct dma_buf_attachment *dmabuf_attachment = NULL; ++ struct sg_table *res_sgt = NULL; ++ ++ dmabuf = dma_buf_get(dmabuf_fd); ++ if (IS_ERR(dmabuf)) { ++ dev_err(dev, "dma_buf_get failed, err=%ld\n", PTR_ERR(dmabuf)); ++ ret = -EINVAL; ++ goto cleanup; ++ } ++ ++ dmabuf_attachment = dma_buf_attach(dmabuf, dev); ++ if (IS_ERR(dmabuf_attachment)) { ++ dev_err(dev, "dma_buf_attach failed, err=%ld\n", PTR_ERR(dmabuf_attachment)); ++ ret = -EINVAL; ++ goto l_buf_get; ++ } ++ ++ res_sgt = dma_buf_map_attachment(dmabuf_attachment, direction); ++ if (IS_ERR(res_sgt)) { ++ dev_err(dev, "dma_buf_map_attachment failed, err=%ld\n", PTR_ERR(res_sgt)); ++ goto l_buf_attach; ++ } ++ ++ *sgt = *res_sgt; ++ ++ dmabuf_info->dmabuf = dmabuf; ++ dmabuf_info->dmabuf_attachment = dmabuf_attachment; ++ dmabuf_info->dmabuf_sg_table = res_sgt; ++ return 0; ++ ++l_buf_attach: ++ dma_buf_detach(dmabuf, dmabuf_attachment); ++l_buf_get: ++ dma_buf_put(dmabuf); ++cleanup: ++ return ret; ++} ++ ++static void hailo_unmap_dmabuf(struct hailo_vdma_buffer *vdma_buffer) ++{ ++ dma_buf_unmap_attachment(vdma_buffer->dmabuf_info.dmabuf_attachment, vdma_buffer->dmabuf_info.dmabuf_sg_table, vdma_buffer->data_direction); ++ dma_buf_detach(vdma_buffer->dmabuf_info.dmabuf, vdma_buffer->dmabuf_info.dmabuf_attachment); ++ dma_buf_put(vdma_buffer->dmabuf_info.dmabuf); ++} ++ ++#else /* LINUX_VERSION_CODE >= KERNEL_VERSION( 3, 3, 0 ) */ ++ ++static int hailo_map_dmabuf(struct device *dev, int dmabuf_fd, enum dma_data_direction direction, struct sg_table *sgt, ++ struct hailo_dmabuf_info *dmabuf_info) ++{ ++ (void) dmabuf_fd; ++ (void) direction; ++ (void) sgt; ++ (void) mapped_buffer; ++ dev_err(dev, "dmabuf not supported in kernel versions lower than 3.3.0\n"); ++ return -EINVAL; ++} ++ ++static void hailo_unmap_dmabuf(struct hailo_vdma_buffer *vdma_buffer) ++{ ++ dev_err(vdma_buffer->device, "dmabuf not supported in kernel versions lower than 3.3.0\n"); ++ return -EINVAL; ++} ++ ++#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION( 3, 3, 0 ) */ ++ + struct hailo_vdma_buffer *hailo_vdma_buffer_map(struct device *dev, +- void __user *user_address, size_t size, enum dma_data_direction direction, +- struct hailo_vdma_low_memory_buffer *low_mem_driver_allocated_buffer) ++ uintptr_t user_address, size_t size, enum dma_data_direction direction, ++ enum hailo_dma_buffer_type buffer_type, struct hailo_vdma_low_memory_buffer *low_mem_driver_allocated_buffer) + { + int ret = -EINVAL; + struct hailo_vdma_buffer *mapped_buffer = NULL; + struct sg_table sgt = {0}; + struct vm_area_struct *vma = NULL; + bool is_mmio = false; ++ struct hailo_dmabuf_info dmabuf_info = {0}; + + mapped_buffer = kzalloc(sizeof(*mapped_buffer), GFP_KERNEL); + if (NULL == mapped_buffer) { +@@ -40,17 +120,19 @@ struct hailo_vdma_buffer *hailo_vdma_buf + goto cleanup; + } + +- if (IS_ENABLED(HAILO_SUPPORT_MMIO_DMA_MAPPING)) { +- vma = find_vma(current->mm, (uintptr_t)user_address); ++ if (IS_ENABLED(HAILO_SUPPORT_MMIO_DMA_MAPPING) && (HAILO_DMA_DMABUF_BUFFER != buffer_type)) { ++ vma = find_vma(current->mm, user_address); + if (NULL == vma) { +- dev_err(dev, "no vma for virt_addr/size = 0x%08lx/0x%08zx\n", (uintptr_t)user_address, size); ++ dev_err(dev, "no vma for virt_addr/size = 0x%08lx/0x%08zx\n", user_address, size); + ret = -EFAULT; + goto cleanup; + } + } + ++ // TODO: is MMIO DMA MAPPINGS STILL needed after dmabuf + if (IS_ENABLED(HAILO_SUPPORT_MMIO_DMA_MAPPING) && +- (MMIO_AND_NO_PAGES_VMA_MASK == (vma->vm_flags & MMIO_AND_NO_PAGES_VMA_MASK))) { ++ (MMIO_AND_NO_PAGES_VMA_MASK == (vma->vm_flags & MMIO_AND_NO_PAGES_VMA_MASK)) && ++ (HAILO_DMA_DMABUF_BUFFER != buffer_type)) { + // user_address represents memory mapped I/O and isn't backed by 'struct page' (only by pure pfn) + if (NULL != low_mem_driver_allocated_buffer) { + // low_mem_driver_allocated_buffer are backed by regular 'struct page' addresses, just in low memory +@@ -66,6 +148,14 @@ struct hailo_vdma_buffer *hailo_vdma_buf + } + + is_mmio = true; ++ ++ } else if (HAILO_DMA_DMABUF_BUFFER == buffer_type) { ++ // Content user_address in case of dmabuf is fd - for now ++ ret = hailo_map_dmabuf(dev, user_address, direction, &sgt, &dmabuf_info); ++ if (ret < 0) { ++ dev_err(dev, "Failed mapping dmabuf\n"); ++ goto cleanup; ++ } + } else { + // user_address is a standard 'struct page' backed memory address + ret = prepare_sg_table(&sgt, user_address, size, low_mem_driver_allocated_buffer); +@@ -88,6 +178,7 @@ struct hailo_vdma_buffer *hailo_vdma_buf + mapped_buffer->data_direction = direction; + mapped_buffer->sg_table = sgt; + mapped_buffer->is_mmio = is_mmio; ++ mapped_buffer->dmabuf_info = dmabuf_info; + + return mapped_buffer; + +@@ -103,11 +194,16 @@ static void unmap_buffer(struct kref *kr + { + struct hailo_vdma_buffer *buf = container_of(kref, struct hailo_vdma_buffer, kref); + +- if (!buf->is_mmio) { +- dma_unmap_sg(buf->device, buf->sg_table.sgl, buf->sg_table.orig_nents, buf->data_direction); +- } ++ // If dmabuf - unmap and detatch dmabuf ++ if (NULL != buf->dmabuf_info.dmabuf) { ++ hailo_unmap_dmabuf(buf); ++ } else { ++ if (!buf->is_mmio) { ++ dma_unmap_sg(buf->device, buf->sg_table.sgl, buf->sg_table.orig_nents, buf->data_direction); ++ } + +- clear_sg_table(&buf->sg_table); ++ clear_sg_table(&buf->sg_table); ++ } + kfree(buf); + } + +@@ -164,8 +260,9 @@ void hailo_vdma_buffer_sync(struct hailo + struct hailo_vdma_buffer *mapped_buffer, enum hailo_vdma_buffer_sync_type sync_type, + size_t offset, size_t size) + { +- if (IS_ENABLED(HAILO_SUPPORT_MMIO_DMA_MAPPING) && mapped_buffer->is_mmio) { +- // MMIO buffers don't need to be sync'd ++ if ((IS_ENABLED(HAILO_SUPPORT_MMIO_DMA_MAPPING) && mapped_buffer->is_mmio) || ++ (NULL != mapped_buffer->dmabuf_info.dmabuf)) { ++ // MMIO buffers and dmabufs don't need to be sync'd + return; + } + +@@ -404,7 +501,8 @@ void hailo_vdma_clear_continuous_buffer_ + + // Assumes the provided user_address belongs to the vma and that MMIO_AND_NO_PAGES_VMA_MASK bits are set under + // vma->vm_flags. This is validated in hailo_vdma_buffer_map, and won't be checked here +-static int map_mmio_address(void __user* user_address, u32 size, struct vm_area_struct *vma, ++#if defined(HAILO_SUPPORT_MMIO_DMA_MAPPING) ++static int map_mmio_address(uintptr_t user_address, u32 size, struct vm_area_struct *vma, + struct sg_table *sgt) + { + int ret = -EINVAL; +@@ -413,7 +511,7 @@ static int map_mmio_address(void __user* + unsigned long next_pfn = 0; + phys_addr_t phys_addr = 0; + dma_addr_t mmio_dma_address = 0; +- const uintptr_t virt_addr = (uintptr_t)user_address; ++ const uintptr_t virt_addr = user_address; + const u32 vma_size = vma->vm_end - vma->vm_start + 1; + const uintptr_t num_pages = PFN_UP(virt_addr + size) - PFN_DOWN(virt_addr); + +@@ -462,8 +560,21 @@ static int map_mmio_address(void __user* + + return 0; + } ++#else /* defined(HAILO_SUPPORT_MMIO_DMA_MAPPING) */ ++static int map_mmio_address(uintptr_t user_address, u32 size, struct vm_area_struct *vma, ++ struct sg_table *sgt) ++{ ++ (void) user_address; ++ (void) size; ++ (void) vma; ++ (void) sgt; ++ pr_err("MMIO DMA MAPPINGS are not supported in this kernel version\n"); ++ return -EINVAL; ++} ++#endif /* defined(HAILO_SUPPORT_MMIO_DMA_MAPPING) */ ++ + +-static int prepare_sg_table(struct sg_table *sg_table, void __user *user_address, u32 size, ++static int prepare_sg_table(struct sg_table *sg_table, uintptr_t user_address, u32 size, + struct hailo_vdma_low_memory_buffer *low_mem_driver_allocated_buffer) + { + int ret = -EINVAL; +@@ -482,8 +593,7 @@ static int prepare_sg_table(struct sg_ta + // Check whether mapping user allocated buffer or driver allocated low memory buffer + if (NULL == low_mem_driver_allocated_buffer) { + mmap_read_lock(current->mm); +- pinned_pages = get_user_pages_compact((unsigned long)user_address, +- npages, FOLL_WRITE | FOLL_FORCE, pages); ++ pinned_pages = get_user_pages_compact(user_address, npages, FOLL_WRITE | FOLL_FORCE, pages); + mmap_read_unlock(current->mm); + + if (pinned_pages < 0) { +--- a/drivers/media/pci/hailo/vdma/memory.h ++++ b/drivers/media/pci/hailo/vdma/memory.h +@@ -11,8 +11,8 @@ + + #include "vdma/vdma.h" + +-struct hailo_vdma_buffer *hailo_vdma_buffer_map(struct device *dev, +- void __user *user_address, size_t size, enum dma_data_direction direction, ++struct hailo_vdma_buffer *hailo_vdma_buffer_map(struct device *dev, uintptr_t user_address, size_t size, ++ enum dma_data_direction direction, enum hailo_dma_buffer_type buffer_type, + struct hailo_vdma_low_memory_buffer *low_mem_driver_allocated_buffer); + void hailo_vdma_buffer_get(struct hailo_vdma_buffer *buf); + void hailo_vdma_buffer_put(struct hailo_vdma_buffer *buf); +--- a/drivers/media/pci/hailo/vdma/vdma.c ++++ b/drivers/media/pci/hailo/vdma/vdma.c +@@ -21,7 +21,7 @@ + + + static struct hailo_vdma_engine* init_vdma_engines(struct device *dev, +- struct hailo_resource *channel_registers_per_engine, size_t engines_count) ++ struct hailo_resource *channel_registers_per_engine, size_t engines_count, u32 src_channels_bitmask) + { + struct hailo_vdma_engine *engines = NULL; + u8 i = 0; +@@ -33,7 +33,7 @@ static struct hailo_vdma_engine* init_vd + } + + for (i = 0; i < engines_count; i++) { +- hailo_vdma_engine_init(&engines[i], i, &channel_registers_per_engine[i]); ++ hailo_vdma_engine_init(&engines[i], i, &channel_registers_per_engine[i], src_channels_bitmask); + } + + return engines; +@@ -72,7 +72,8 @@ int hailo_vdma_controller_init(struct ha + controller->dev = dev; + + controller->vdma_engines_count = engines_count; +- controller->vdma_engines = init_vdma_engines(dev, channel_registers_per_engine, engines_count); ++ controller->vdma_engines = init_vdma_engines(dev, channel_registers_per_engine, engines_count, ++ vdma_hw->src_channels_bitmask); + if (IS_ERR(controller->vdma_engines)) { + dev_err(dev, "Failed initialized vdma engines\n"); + return PTR_ERR(controller->vdma_engines); +@@ -113,36 +114,27 @@ void hailo_vdma_update_interrupts_mask(s + controller->ops->update_channel_interrupts(controller, engine_index, engine->enabled_channels); + } + +-void hailo_vdma_engine_interrupts_disable(struct hailo_vdma_controller *controller, +- struct hailo_vdma_engine *engine, u8 engine_index, u32 channels_bitmap) +-{ +- unsigned long irq_saved_flags = 0; +- // In case of FLR, the vdma registers will be NULL +- const bool is_device_up = (NULL != controller->dev); +- +- hailo_vdma_engine_disable_channel_interrupts(engine, channels_bitmap); +- if (is_device_up) { +- hailo_vdma_update_interrupts_mask(controller, engine_index); +- } +- +- spin_lock_irqsave(&controller->interrupts_lock, irq_saved_flags); +- hailo_vdma_engine_clear_channel_interrupts(engine, channels_bitmap); +- spin_unlock_irqrestore(&controller->interrupts_lock, irq_saved_flags); +- +- hailo_dev_info(controller->dev, "Disabled interrupts for engine %u, channels bitmap 0x%x\n", +- engine_index, channels_bitmap); +-} +- + void hailo_vdma_file_context_finalize(struct hailo_vdma_file_context *context, + struct hailo_vdma_controller *controller, struct file *filp) + { + size_t engine_index = 0; + struct hailo_vdma_engine *engine = NULL; + const u32 channels_bitmap = 0xFFFFFFFF; // disable all channel interrupts ++ unsigned long irq_saved_flags = 0; ++ // In case of FLR, the vdma registers will be NULL ++ const bool is_device_up = (NULL != controller->dev); + + if (filp == controller->used_by_filp) { + for_each_vdma_engine(controller, engine, engine_index) { +- hailo_vdma_engine_interrupts_disable(controller, engine, engine_index, channels_bitmap); ++ hailo_vdma_engine_disable_channels(engine, channels_bitmap); ++ ++ if (is_device_up) { ++ hailo_vdma_update_interrupts_mask(controller, engine_index); ++ } ++ ++ spin_lock_irqsave(&controller->interrupts_lock, irq_saved_flags); ++ hailo_vdma_engine_clear_channel_interrupts(engine, channels_bitmap); ++ spin_unlock_irqrestore(&controller->interrupts_lock, irq_saved_flags); + } + } + +@@ -178,10 +170,10 @@ long hailo_vdma_ioctl(struct hailo_vdma_ + unsigned int cmd, unsigned long arg, struct file *filp, struct semaphore *mutex, bool *should_up_board_mutex) + { + switch (cmd) { +- case HAILO_VDMA_INTERRUPTS_ENABLE: +- return hailo_vdma_interrupts_enable_ioctl(controller, arg); +- case HAILO_VDMA_INTERRUPTS_DISABLE: +- return hailo_vdma_interrupts_disable_ioctl(controller, arg); ++ case HAILO_VDMA_ENABLE_CHANNELS: ++ return hailo_vdma_enable_channels_ioctl(controller, arg); ++ case HAILO_VDMA_DISABLE_CHANNELS: ++ return hailo_vdma_disable_channels_ioctl(controller, arg); + case HAILO_VDMA_INTERRUPTS_WAIT: + return hailo_vdma_interrupts_wait_ioctl(controller, arg, mutex, should_up_board_mutex); + case HAILO_VDMA_INTERRUPTS_READ_TIMESTAMPS: +@@ -196,8 +188,8 @@ long hailo_vdma_ioctl(struct hailo_vdma_ + return hailo_desc_list_create_ioctl(context, controller, arg); + case HAILO_DESC_LIST_RELEASE: + return hailo_desc_list_release_ioctl(context, controller, arg); +- case HAILO_DESC_LIST_BIND_VDMA_BUFFER: +- return hailo_desc_list_bind_vdma_buffer(context, controller, arg); ++ case HAILO_DESC_LIST_PROGRAM: ++ return hailo_desc_list_program_ioctl(context, controller, arg); + case HAILO_VDMA_LOW_MEMORY_BUFFER_ALLOC: + return hailo_vdma_low_memory_buffer_alloc_ioctl(context, controller, arg); + case HAILO_VDMA_LOW_MEMORY_BUFFER_FREE: +@@ -216,28 +208,6 @@ long hailo_vdma_ioctl(struct hailo_vdma_ + } + } + +-static int desc_list_mmap(struct hailo_vdma_controller *controller, +- struct hailo_descriptors_list_buffer *vdma_descriptors_buffer, struct vm_area_struct *vma) +-{ +- int err = 0; +- unsigned long vsize = vma->vm_end - vma->vm_start; +- +- if (vsize > vdma_descriptors_buffer->buffer_size) { +- hailo_dev_err(controller->dev, "Requested size to map (%lx) is larger than the descriptor list size(%x)\n", +- vsize, vdma_descriptors_buffer->buffer_size); +- return -EINVAL; +- } +- +- err = dma_mmap_coherent(controller->dev, vma, vdma_descriptors_buffer->kernel_address, +- vdma_descriptors_buffer->dma_address, vsize); +- if (err != 0) { +- hailo_dev_err(controller->dev, " Failed mmap descriptors %d\n", err); +- return err; +- } +- +- return 0; +-} +- + static int low_memory_buffer_mmap(struct hailo_vdma_controller *controller, + struct hailo_vdma_low_memory_buffer *vdma_buffer, struct vm_area_struct *vma) + { +@@ -300,15 +270,11 @@ static int continuous_buffer_mmap(struct + int hailo_vdma_mmap(struct hailo_vdma_file_context *context, struct hailo_vdma_controller *controller, + struct vm_area_struct *vma, uintptr_t vdma_handle) + { +- struct hailo_descriptors_list_buffer *vdma_descriptors_buffer = NULL; + struct hailo_vdma_low_memory_buffer *low_memory_buffer = NULL; + struct hailo_vdma_continuous_buffer *continuous_buffer = NULL; + + hailo_dev_info(controller->dev, "Map vdma_handle %llu\n", (u64)vdma_handle); +- if (NULL != (vdma_descriptors_buffer = hailo_vdma_find_descriptors_buffer(context, vdma_handle))) { +- return desc_list_mmap(controller, vdma_descriptors_buffer, vma); +- } +- else if (NULL != (low_memory_buffer = hailo_vdma_find_low_memory_buffer(context, vdma_handle))) { ++ if (NULL != (low_memory_buffer = hailo_vdma_find_low_memory_buffer(context, vdma_handle))) { + return low_memory_buffer_mmap(controller, low_memory_buffer, vma); + } + else if (NULL != (continuous_buffer = hailo_vdma_find_continuous_buffer(context, vdma_handle))) { +--- a/drivers/media/pci/hailo/vdma/vdma.h ++++ b/drivers/media/pci/hailo/vdma/vdma.h +@@ -16,6 +16,8 @@ + #include + #include + #include ++#include ++#include + + #define VDMA_CHANNEL_CONTROL_REG_OFFSET(channel_index, direction) (((direction) == DMA_TO_DEVICE) ? \ + (((channel_index) << 5) + 0x0) : (((channel_index) << 5) + 0x10)) +@@ -28,6 +30,22 @@ + ((u8*)((vdma_registers)->address) + VDMA_CHANNEL_NUM_PROC_OFFSET(channel_index, direction)) + + ++// dmabuf is supported from linux kernel version 3.3 ++#if LINUX_VERSION_CODE < KERNEL_VERSION( 3, 3, 0 ) ++// Make dummy struct with one byte (C standards does not allow empty struct) - in order to not have to ifdef everywhere ++struct hailo_dmabuf_info { ++ uint8_t dummy; ++}; ++#else ++// dmabuf_sg_table is needed because in dma_buf_unmap_attachment() the sg_table's address has to match the ++// The one returned from dma_buf_map_attachment() - otherwise we would need to malloc each time ++struct hailo_dmabuf_info { ++ struct dma_buf *dmabuf; ++ struct dma_buf_attachment *dmabuf_attachment; ++ struct sg_table *dmabuf_sg_table; ++}; ++#endif // LINUX_VERSION_CODE < KERNEL_VERSION( 3, 3, 0 ) ++ + struct hailo_vdma_buffer { + struct list_head mapped_user_buffer_list; + size_t handle; +@@ -35,7 +53,7 @@ struct hailo_vdma_buffer { + struct kref kref; + struct device *device; + +- void __user *user_address; ++ uintptr_t user_address; + u32 size; + enum dma_data_direction data_direction; + struct sg_table sg_table; +@@ -44,7 +62,10 @@ struct hailo_vdma_buffer { + // 'struct page' (only by pure pfn). On this case, accessing to the page, + // or calling APIs that access the page (e.g. dma_sync_sg_for_cpu) is not + // allowed. +- bool is_mmio; ++ bool is_mmio; ++ ++ // Relevant paramaters that need to be saved in case of dmabuf - otherwise struct pointers will be NULL ++ struct hailo_dmabuf_info dmabuf_info; + }; + + // Continuous buffer that holds a descriptor list. +@@ -53,7 +74,7 @@ struct hailo_descriptors_list_buffer { + uintptr_t handle; + void *kernel_address; + dma_addr_t dma_address; +- u32 buffer_size; ++ u32 buffer_size; + struct hailo_vdma_descriptors_list desc_list; + }; + +@@ -120,9 +141,6 @@ int hailo_vdma_controller_init(struct ha + void hailo_vdma_update_interrupts_mask(struct hailo_vdma_controller *controller, + size_t engine_index); + +-void hailo_vdma_engine_interrupts_disable(struct hailo_vdma_controller *controller, +- struct hailo_vdma_engine *engine, u8 engine_index, u32 channels_bitmap); +- + void hailo_vdma_file_context_init(struct hailo_vdma_file_context *context); + void hailo_vdma_file_context_finalize(struct hailo_vdma_file_context *context, + struct hailo_vdma_controller *controller, struct file *filp); diff --git a/target/linux/bcm27xx/patches-6.6/950-1236-media-rpivid-Make-SPS-PPS-optional-in-a-request.patch b/target/linux/bcm27xx/patches-6.6/950-1236-media-rpivid-Make-SPS-PPS-optional-in-a-request.patch new file mode 100644 index 00000000000..26edb5558a3 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1236-media-rpivid-Make-SPS-PPS-optional-in-a-request.patch @@ -0,0 +1,80 @@ +From cf64a1dfecc2dc418efdd61701c1a4b185ab4761 Mon Sep 17 00:00:00 2001 +From: John Cox +Date: Fri, 23 Aug 2024 16:48:38 +0100 +Subject: [PATCH 1236/1350] media/rpivid: Make SPS / PPS optional in a request + +SPS & PPS are optional in requests. Fix. The framework keeps the last +value so this is mostly a matter of changing .required to false when +requesting the controls. Check that SPS has ever been set on frame +start, PPS is valid if all zeros so is at best tricky to check. + +Signed-off-by: John Cox +--- + drivers/staging/media/rpivid/rpivid.c | 4 ++-- + drivers/staging/media/rpivid/rpivid_h265.c | 6 ++++++ + drivers/staging/media/rpivid/rpivid_video.c | 5 ----- + drivers/staging/media/rpivid/rpivid_video.h | 5 +++++ + 4 files changed, 13 insertions(+), 7 deletions(-) + +--- a/drivers/staging/media/rpivid/rpivid.c ++++ b/drivers/staging/media/rpivid/rpivid.c +@@ -40,14 +40,14 @@ static const struct rpivid_control rpivi + .id = V4L2_CID_STATELESS_HEVC_SPS, + .ops = &rpivid_hevc_sps_ctrl_ops, + }, +- .required = true, ++ .required = false, + }, + { + .cfg = { + .id = V4L2_CID_STATELESS_HEVC_PPS, + .ops = &rpivid_hevc_pps_ctrl_ops, + }, +- .required = true, ++ .required = false, + }, + { + .cfg = { +--- a/drivers/staging/media/rpivid/rpivid_h265.c ++++ b/drivers/staging/media/rpivid/rpivid_h265.c +@@ -1726,6 +1726,12 @@ static void rpivid_h265_setup(struct rpi + unsigned int ctb_size_y; + bool sps_changed = false; + ++ if (!is_sps_set(run->h265.sps)) { ++ v4l2_warn(&dev->v4l2_dev, "SPS never set\n"); ++ goto fail; ++ } ++ // Can't check for PPS easily as all 0's looks valid to me ++ + if (memcmp(&s->sps, run->h265.sps, sizeof(s->sps)) != 0) { + /* SPS changed */ + v4l2_info(&dev->v4l2_dev, "SPS changed\n"); +--- a/drivers/staging/media/rpivid/rpivid_video.c ++++ b/drivers/staging/media/rpivid/rpivid_video.c +@@ -257,11 +257,6 @@ static int rpivid_hevc_validate_sps(cons + return 1; + } + +-static inline int is_sps_set(const struct v4l2_ctrl_hevc_sps * const sps) +-{ +- return sps && sps->pic_width_in_luma_samples != 0; +-} +- + static u32 pixelformat_from_sps(const struct v4l2_ctrl_hevc_sps * const sps, + const int index) + { +--- a/drivers/staging/media/rpivid/rpivid_video.h ++++ b/drivers/staging/media/rpivid/rpivid_video.h +@@ -20,6 +20,11 @@ struct rpivid_format { + unsigned int capabilities; + }; + ++static inline int is_sps_set(const struct v4l2_ctrl_hevc_sps * const sps) ++{ ++ return sps && sps->pic_width_in_luma_samples != 0; ++} ++ + extern const struct v4l2_ioctl_ops rpivid_ioctl_ops; + + int rpivid_queue_init(void *priv, struct vb2_queue *src_vq, diff --git a/target/linux/bcm27xx/patches-6.6/950-1238-piscreen-overlay-Add-invert-x-y-and-swapxy.patch b/target/linux/bcm27xx/patches-6.6/950-1238-piscreen-overlay-Add-invert-x-y-and-swapxy.patch new file mode 100644 index 00000000000..0eeb8ae0d71 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1238-piscreen-overlay-Add-invert-x-y-and-swapxy.patch @@ -0,0 +1,37 @@ +From 31be188fb945560c193020b19773625421847112 Mon Sep 17 00:00:00 2001 +From: Satadru Pramanik +Date: Wed, 4 Sep 2024 08:40:42 -0400 +Subject: [PATCH 1238/1350] piscreen-overlay: Add invert[x,y] and swapxy + +Signed-off-by: Satadru Pramanik +--- + arch/arm/boot/dts/overlays/README | 6 ++++++ + arch/arm/boot/dts/overlays/piscreen-overlay.dts | 3 +++ + 2 files changed, 9 insertions(+) + +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -3694,6 +3694,12 @@ Params: speed Display + drm Select the DRM/KMS driver instead of the FBTFT + one + ++ invx Touchscreen inverted x axis ++ ++ invy Touchscreen inverted y axis ++ ++ swapxy Touchscreen swapped x y axis ++ + + Name: piscreen2r + Info: PiScreen 2 with resistive TP display by OzzMaker.com +--- a/arch/arm/boot/dts/overlays/piscreen-overlay.dts ++++ b/arch/arm/boot/dts/overlays/piscreen-overlay.dts +@@ -103,5 +103,8 @@ + xohms = <&piscreen_ts>,"ti,x-plate-ohms;0"; + drm = <&piscreen>,"compatible=waveshare,rpi-lcd-35", + <&piscreen>,"reset-gpios:8=",; ++ invx = <&piscreen_ts>,"touchscreen-inverted-x?"; ++ invy = <&piscreen_ts>,"touchscreen-inverted-y?"; ++ swapxy = <&piscreen_ts>,"touchscreen-swapped-x-y!"; + }; + }; diff --git a/target/linux/bcm27xx/patches-6.6/950-1239-drivers-gpu-drm-panel-Added-waveshare-5.0inch-6.25in.patch b/target/linux/bcm27xx/patches-6.6/950-1239-drivers-gpu-drm-panel-Added-waveshare-5.0inch-6.25in.patch new file mode 100644 index 00000000000..96e3b478d4e --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1239-drivers-gpu-drm-panel-Added-waveshare-5.0inch-6.25in.patch @@ -0,0 +1,82 @@ +From f955b7838f9ce72e48b29e58d65e0642d097c8b3 Mon Sep 17 00:00:00 2001 +From: eng33 +Date: Wed, 4 Sep 2024 10:48:22 +0800 +Subject: [PATCH 1239/1350] drivers:gpu:drm:panel: Added waveshare 5.0inch, + 6.25inch, and 8.8inch dsi screen devices + +Signed-off-by: eng33 +--- + drivers/gpu/drm/panel/panel-waveshare-dsi.c | 55 +++++++++++++++++++++ + 1 file changed, 55 insertions(+) + +--- a/drivers/gpu/drm/panel/panel-waveshare-dsi.c ++++ b/drivers/gpu/drm/panel/panel-waveshare-dsi.c +@@ -150,6 +150,51 @@ static const struct drm_display_mode ws_ + .vtotal = 720 + 8 + 4 + 16, + }; + ++/* 5.0inch 720x1280 ++ * https://www.waveshare.com/5inch-dsi-lcd-d.htm ++ */ ++static const struct drm_display_mode ws_panel_5_0_mode = { ++ .clock = 83333, ++ .hdisplay = 720, ++ .hsync_start = 720 + 100, ++ .hsync_end = 720 + 100 + 80, ++ .htotal = 720 + 100 + 80 + 100, ++ .vdisplay = 1280, ++ .vsync_start = 1280 + 20, ++ .vsync_end = 1280 + 20 + 20, ++ .vtotal = 1280 + 20 + 20 + 20, ++}; ++ ++/* 6.25inch 720x1560 ++ * https://www.waveshare.com/6.25inch-dsi-lcd.htm ++ */ ++static const struct drm_display_mode ws_panel_6_25_mode = { ++ .clock = 83333, ++ .hdisplay = 720, ++ .hsync_start = 720 + 50, ++ .hsync_end = 720 + 50 + 50, ++ .htotal = 720 + 50 + 50 + 50, ++ .vdisplay = 1560, ++ .vsync_start = 1560 + 20, ++ .vsync_end = 1560 + 20 + 20, ++ .vtotal = 1560 + 20 + 20 + 20, ++}; ++ ++/* 8.8inch 480x1920 ++ * https://www.waveshare.com/8.8inch-dsi-lcd.htm ++ */ ++static const struct drm_display_mode ws_panel_8_8_mode = { ++ .clock = 83333, ++ .hdisplay = 480, ++ .hsync_start = 480 + 50, ++ .hsync_end = 480 + 50 + 50, ++ .htotal = 480 + 50 + 50 + 50, ++ .vdisplay = 1920, ++ .vsync_start = 1920 + 20, ++ .vsync_end = 1920 + 20 + 20, ++ .vtotal = 1920 + 20 + 20 + 20, ++}; ++ + static struct ws_panel *panel_to_ts(struct drm_panel *panel) + { + return container_of(panel, struct ws_panel, base); +@@ -413,6 +458,16 @@ static const struct of_device_id ws_pane + .compatible = "waveshare,4inch-panel", + .data = &ws_panel_4_mode, + }, { ++ .compatible = "waveshare,5.0inch-panel", ++ .data = &ws_panel_5_0_mode, ++ }, { ++ .compatible = "waveshare,6.25inch-panel", ++ .data = &ws_panel_6_25_mode, ++ }, { ++ .compatible = "waveshare,8.8inch-panel", ++ .data = &ws_panel_8_8_mode, ++ }, { ++ }, { + /* sentinel */ + } + }; diff --git a/target/linux/bcm27xx/patches-6.6/950-1240-arch-arm-boot-dts-overlays-Added-waveshare-5.0inch-6.patch b/target/linux/bcm27xx/patches-6.6/950-1240-arch-arm-boot-dts-overlays-Added-waveshare-5.0inch-6.patch new file mode 100644 index 00000000000..11f504a1879 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1240-arch-arm-boot-dts-overlays-Added-waveshare-5.0inch-6.patch @@ -0,0 +1,27 @@ +From 769cd349d65fb29aaa8f443f9c7a701205b0409c Mon Sep 17 00:00:00 2001 +From: eng33 +Date: Wed, 4 Sep 2024 10:56:13 +0800 +Subject: [PATCH 1240/1350] arch:arm:boot:dts:overlays: Added waveshare + 5.0inch, 6.25inch, and 8.8inch dsi screen dts + +Signed-off-by: eng33 +--- + .../dts/overlays/vc4-kms-dsi-waveshare-panel-overlay.dts | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/arch/arm/boot/dts/overlays/vc4-kms-dsi-waveshare-panel-overlay.dts ++++ b/arch/arm/boot/dts/overlays/vc4-kms-dsi-waveshare-panel-overlay.dts +@@ -113,6 +113,13 @@ + 4_0_inchC = <&panel>, "compatible=waveshare,4inch-panel", + <&touch>, "touchscreen-size-x:0=720", + <&touch>, "touchscreen-size-y:0=720"; ++ 5_0_inch = <&panel>, "compatible=waveshare,5.0inch-panel", ++ <&touch>, "touchscreen-inverted-x?", ++ <&touch>, "touchscreen-inverted-y?"; ++ 6_25_inch = <&panel>, "compatible=waveshare,6.25inch-panel", ++ <&touch>, "touchscreen-inverted-x?", ++ <&touch>, "touchscreen-inverted-y?"; ++ 8_8_inch = <&panel>, "compatible=waveshare,8.8inch-panel"; + i2c1 = <&i2c_frag>, "target:0=",<&i2c1>, + <0>, "-3-4+5"; + disable_touch = <&touch>, "status=disabled"; diff --git a/target/linux/bcm27xx/patches-6.6/950-1241-arch-arm-boot-dts-overlays-Added-waveshare-5.0inch-6.patch b/target/linux/bcm27xx/patches-6.6/950-1241-arch-arm-boot-dts-overlays-Added-waveshare-5.0inch-6.patch new file mode 100644 index 00000000000..0d592124539 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1241-arch-arm-boot-dts-overlays-Added-waveshare-5.0inch-6.patch @@ -0,0 +1,23 @@ +From 3d39588b52abb06ed2b4b0d2db026133a920758b Mon Sep 17 00:00:00 2001 +From: eng33 +Date: Thu, 5 Sep 2024 17:19:56 +0800 +Subject: [PATCH 1241/1350] arch:arm:boot:dts:overlays: Added waveshare + 5.0inch, 6.25inch, and 8.8inch dsi screen description + +Signed-off-by: eng33 +--- + arch/arm/boot/dts/overlays/README | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -5233,6 +5233,9 @@ Params: 2_8_inch 2.8" 480 + 3_4_inch 3.4" 800x800 round + 4_0_inch 4.0" 480x800 + 4_0_inchC 4.0" 720x720 ++ 5_0_inch 5.0" 720x1280 ++ 6_25_inch 6.25" 720x1560 ++ 8_8_inch 8.8" 480x1920 + 7_0_inchC 7.0" C 1024x600 + 7_9_inch 7.9" 400x1280 + 8_0_inch 8.0" 1280x800 diff --git a/target/linux/bcm27xx/patches-6.6/950-1242-spi-rp2040-gpio-bridge-Add-debugfs-progress-indicato.patch b/target/linux/bcm27xx/patches-6.6/950-1242-spi-rp2040-gpio-bridge-Add-debugfs-progress-indicato.patch new file mode 100644 index 00000000000..4d7bc4d0387 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1242-spi-rp2040-gpio-bridge-Add-debugfs-progress-indicato.patch @@ -0,0 +1,89 @@ +From 4d219b15a7a01a14c1be1eeee9a939732130d30a Mon Sep 17 00:00:00 2001 +From: Naushir Patuck +Date: Tue, 13 Aug 2024 13:45:54 +0100 +Subject: [PATCH 1242/1350] spi: rp2040-gpio-bridge: Add debugfs progress + indicator + +Useful for tracking upload progress via userspace. + +Signed-off-by: Naushir Patuck +--- + drivers/spi/spi-rp2040-gpio-bridge.c | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +--- a/drivers/spi/spi-rp2040-gpio-bridge.c ++++ b/drivers/spi/spi-rp2040-gpio-bridge.c +@@ -6,6 +6,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -91,6 +92,9 @@ enum rp2040_gbdg_fixed_size_commands { + struct rp2040_gbdg { + struct spi_controller *controller; + ++ struct dentry *debugfs; ++ size_t transfer_progress; ++ + struct i2c_client *client; + struct crypto_shash *shash; + struct shash_desc *shash_desc; +@@ -702,6 +706,7 @@ static int rp2040_gbdg_transfer_cached(s + return 0; + } + ++ priv_data->transfer_progress = 0; + while (length) { + unsigned int xfer = min(length, RP2040_GBDG_BLOCK_SIZE); + +@@ -710,7 +715,9 @@ static int rp2040_gbdg_transfer_cached(s + return ret; + length -= xfer; + data += xfer; ++ priv_data->transfer_progress += xfer; + } ++ priv_data->transfer_progress = 0; + + return 0; + } +@@ -1016,6 +1023,16 @@ static int rp2040_gbdg_power_on(struct r + return 0; + } + ++static int transfer_progress_show(struct seq_file *s, void *data) ++{ ++ struct rp2040_gbdg *rp2040_gbdg = s->private; ++ ++ seq_printf(s, "%zu\n", rp2040_gbdg->transfer_progress); ++ return 0; ++} ++ ++DEFINE_SHOW_ATTRIBUTE(transfer_progress); ++ + static int rp2040_gbdg_probe(struct i2c_client *client) + { + struct rp2040_gbdg_device_info info; +@@ -1023,6 +1040,7 @@ static int rp2040_gbdg_probe(struct i2c_ + struct device *dev = &client->dev; + struct rp2040_gbdg *rp2040_gbdg; + struct device_node *np; ++ char debugfs_name[128]; + int ret; + + np = dev->of_node; +@@ -1136,6 +1154,12 @@ static int rp2040_gbdg_probe(struct i2c_ + + rp2040_gbdg_parse_dt(rp2040_gbdg); + ++ snprintf(debugfs_name, sizeof(debugfs_name), "rp2040-spi:%s", ++ dev_name(dev)); ++ rp2040_gbdg->debugfs = debugfs_create_dir(debugfs_name, NULL); ++ debugfs_create_file("transfer_progress", 0444, rp2040_gbdg->debugfs, ++ rp2040_gbdg, &transfer_progress_fops); ++ + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + diff --git a/target/linux/bcm27xx/patches-6.6/950-1243-media-dt-bindings-i2c-Add-Sony-IMX500.patch b/target/linux/bcm27xx/patches-6.6/950-1243-media-dt-bindings-i2c-Add-Sony-IMX500.patch new file mode 100644 index 00000000000..82e58c12bc5 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1243-media-dt-bindings-i2c-Add-Sony-IMX500.patch @@ -0,0 +1,166 @@ +From 30921ddfa24a5325d0f4980c72f98d20bace87a2 Mon Sep 17 00:00:00 2001 +From: Richard Oliver +Date: Fri, 24 May 2024 11:43:07 +0100 +Subject: [PATCH 1243/1350] media: dt-bindings: i2c: Add Sony IMX500 + +Add YAML device tree binding for the Sony IMX500 CMOS image sensor / +CNN inference engine. Also, add a MAINTAINERS entry. + +Signed-off-by: Richard Oliver +--- + .../bindings/media/i2c/sony,imx500.yaml | 132 ++++++++++++++++++ + MAINTAINERS | 7 + + 2 files changed, 139 insertions(+) + create mode 100644 Documentation/devicetree/bindings/media/i2c/sony,imx500.yaml + +--- /dev/null ++++ b/Documentation/devicetree/bindings/media/i2c/sony,imx500.yaml +@@ -0,0 +1,132 @@ ++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/media/i2c/sony,imx500.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: Sony CMOS Digital Image Sensor and CNN ++ ++maintainers: ++ - Raspberry Pi ++ ++description: |- ++ The Sony IMX500 is a stacked 1/2.3-inch CMOS digital image sensor and inbuilt ++ AI processor with an active array CNN (Convolutional Neural Network) inference ++ engine. The native sensor size is 4056H x 3040V, and the module also contains ++ an in-built ISP for the CNN. The module is programmable through an I2C ++ interface with firmware and neural network uploads being made over SPI. The ++ default I2C address is 0x1A, with an address of 0x10 being selectable via ++ SLASEL. The module also has a second I2C interface available with a fixed ++ address of 0x36. Image data is sent through MIPI CSI-2, which is configured ++ as either 2 or 4 data lanes. ++ ++properties: ++ compatible: ++ const: sony,imx500 ++ ++ reg: ++ description: I2C device address ++ maxItems: 1 ++ ++ clocks: ++ maxItems: 1 ++ ++ clock-names: ++ description: |- ++ Input clock (12 to 27 MHz) ++ items: ++ - const: inck ++ ++ interrupts: ++ maxItems: 1 ++ ++ vana-supply: ++ description: Supply voltage (analog) - 2.7 V ++ ++ vdig-supply: ++ description: Supply voltage (digital) - 0.84 V ++ ++ vif-supply: ++ description: Supply voltage (interface) - 1.8 V ++ ++ reset-gpios: ++ description: |- ++ Sensor reset (XCLR) GPIO ++ ++ Chip clear in lieu of built-in power on reset. To be set 'High' after ++ power supplies are brought up and INCK supplied. ++ ++ port: ++ $ref: /schemas/graph.yaml#/$defs/port-base ++ additionalProperties: false ++ description: | ++ Video output port ++ ++ properties: ++ endpoint: ++ $ref: /schemas/media/video-interfaces.yaml# ++ type: object ++ unevaluatedProperties: false ++ properties: ++ data-lanes: ++ items: ++ - const: 2 ++ - const: 4 ++ clock-noncontinuous: true ++ link-frequencies: true ++ required: ++ - link-frequencies ++ - data-lanes ++ ++ spi: ++ $ref: /schemas/types.yaml#/definitions/phandle ++ description: |- ++ SPI peripheral ++ ++ Optional SPI peripheral for uploading firmware and network weights to AI ++ processor. ++ ++required: ++ - compatible ++ - reg ++ - clocks ++ - clock-names ++ - vana-supply ++ - vdig-supply ++ - vif-supply ++ - port ++ ++examples: ++ - | ++ #include ++ ++ i2c { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ imx500: sensor@1a { ++ compatible = "sony,imx500"; ++ reg = <0x1a>; ++ ++ clocks = <&imx500_clk>; ++ clock-names = "inck"; ++ ++ vana-supply = <&imx500_vana>; /* 2.7 +/- 0.1 V */ ++ vdig-supply = <&imx500_vdig>; /* 0.84 +/- 0.04 V */ ++ vif-supply = <&imx500_vif>; /* 1.8 +/- 0.1 V */ ++ ++ reset-gpios = <&gpio_sensor 0 GPIO_ACTIVE_LOW>; ++ ++ port { ++ imx500_0: endpoint { ++ remote-endpoint = <&csi1_ep>; ++ data-lanes = <1 2>; ++ clock-noncontinuous; ++ link-frequencies = /bits/ 64 <499500000>; ++ }; ++ }; ++ }; ++ }; ++ ++... ++ +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -20127,6 +20127,13 @@ F: Documentation/devicetree/bindings/med + F: Documentation/devicetree/bindings/media/i2c/imx477.yaml + F: drivers/media/i2c/imx477.c + ++SONY IMX500 SENSOR DRIVER ++M: Raspberry Pi Kernel Maintenance ++L: linux-media@vger.kernel.org ++S: Maintained ++T: git git://linuxtv.org/media_tree.git ++F: Documentation/devicetree/bindings/media/i2c/sony,imx500.yaml ++ + SONY IMX519 SENSOR DRIVER + M: Arducam Kernel Maintenance + L: linux-media@vger.kernel.org diff --git a/target/linux/bcm27xx/patches-6.6/950-1244-media-i2c-Add-driver-for-Sony-IMX500-sensor.patch b/target/linux/bcm27xx/patches-6.6/950-1244-media-i2c-Add-driver-for-Sony-IMX500-sensor.patch new file mode 100644 index 00000000000..331e5863a64 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1244-media-i2c-Add-driver-for-Sony-IMX500-sensor.patch @@ -0,0 +1,1675 @@ +From f9b1e0ffdd9b5134d9356d7e09e9c1a065fdfa13 Mon Sep 17 00:00:00 2001 +From: Richard Oliver +Date: Thu, 27 Jun 2024 10:11:44 +0100 +Subject: [PATCH 1244/1350] media: i2c: Add driver for Sony IMX500 sensor + +The Sony IMX500 is a stacked 1/2.3-inch CMOS digital image sensor and +inbuilt AI processor with an active array CNN (Convolutional Neural +Network) inference engine. The native sensor size is 4056H x 3040V, and +the module also contains an in-built ISP for the CNN. The module is +programmable through an I2C interface with firmware and neural network +uploads being made over SPI. This driver supports imaging only. + +Signed-off-by: Richard Oliver +--- + MAINTAINERS | 1 + + drivers/media/i2c/Kconfig | 12 + + drivers/media/i2c/Makefile | 1 + + drivers/media/i2c/imx500.c | 1610 ++++++++++++++++++++++++++++++++++++ + 4 files changed, 1624 insertions(+) + create mode 100644 drivers/media/i2c/imx500.c + +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -20133,6 +20133,7 @@ L: linux-media@vger.kernel.org + S: Maintained + T: git git://linuxtv.org/media_tree.git + F: Documentation/devicetree/bindings/media/i2c/sony,imx500.yaml ++F: drivers/media/i2c/imx500.c + + SONY IMX519 SENSOR DRIVER + M: Arducam Kernel Maintenance +--- a/drivers/media/i2c/Kconfig ++++ b/drivers/media/i2c/Kconfig +@@ -236,6 +236,18 @@ config VIDEO_IMX477 + To compile this driver as a module, choose M here: the + module will be called imx477. + ++config VIDEO_IMX500 ++ tristate "Sony IMX500 sensor support" ++ depends on I2C && VIDEO_DEV ++ select VIDEO_V4L2_SUBDEV_API ++ select V4L2_CCI_I2C ++ help ++ This is a Video4Linux2 sensor driver for the Sony ++ IMX500 camera. ++ ++ To compile this driver as a module, choose M here: the ++ module will be called IMX500. ++ + config VIDEO_IMX519 + tristate "Arducam IMX519 sensor support" + depends on I2C && VIDEO_DEV +--- a/drivers/media/i2c/Makefile ++++ b/drivers/media/i2c/Makefile +@@ -58,6 +58,7 @@ obj-$(CONFIG_VIDEO_IMX355) += imx355.o + obj-$(CONFIG_VIDEO_IMX412) += imx412.o + obj-$(CONFIG_VIDEO_IMX415) += imx415.o + obj-$(CONFIG_VIDEO_IMX477) += imx477.o ++obj-$(CONFIG_VIDEO_IMX500) += imx500.o + obj-$(CONFIG_VIDEO_IMX519) += imx519.o + obj-$(CONFIG_VIDEO_IMX708) += imx708.o + obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o +--- /dev/null ++++ b/drivers/media/i2c/imx500.c +@@ -0,0 +1,1610 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * A V4L2 driver for Sony IMX500 cameras. ++ * Copyright (C) 2024, Raspberry Pi Ltd ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Chip ID */ ++#define IMX500_REG_CHIP_ID CCI_REG16(0x0016) ++#define IMX500_CHIP_ID 0x0500 ++ ++#define IMX500_REG_MODE_SELECT CCI_REG8(0x0100) ++#define IMX500_MODE_STANDBY 0x00 ++#define IMX500_MODE_STREAMING 0x01 ++ ++#define IMX500_REG_IMAGE_ONLY_MODE CCI_REG8(0xa700) ++#define IMX500_IMAGE_ONLY_FALSE 0x00 ++#define IMX500_IMAGE_ONLY_TRUE 0x01 ++ ++#define IMX500_REG_ORIENTATION CCI_REG8(0x101) ++ ++#define IMX500_XCLK_FREQ 24000000 ++ ++#define IMX500_DEFAULT_LINK_FREQ 444000000 ++ ++#define IMX500_PIXEL_RATE 744000000 ++ ++/* V_TIMING internal */ ++#define IMX500_REG_FRAME_LENGTH CCI_REG16(0x0340) ++#define IMX500_FRAME_LENGTH_MAX 0xffdc ++#define IMX500_VBLANK_MIN 4 ++ ++/* H_TIMING internal */ ++#define IMX500_REG_LINE_LENGTH CCI_REG16(0x0342) ++#define IMX500_LINE_LENGTH_MAX 0xfff0 ++ ++/* Long exposure multiplier */ ++#define IMX500_LONG_EXP_SHIFT_MAX 7 ++#define IMX500_LONG_EXP_SHIFT_REG CCI_REG8(0x3210) ++ ++/* Exposure control */ ++#define IMX500_REG_EXPOSURE CCI_REG16(0x0202) ++#define IMX500_EXPOSURE_OFFSET 22 ++#define IMX500_EXPOSURE_MIN 8 ++#define IMX500_EXPOSURE_STEP 1 ++#define IMX500_EXPOSURE_DEFAULT 0x640 ++#define IMX500_EXPOSURE_MAX (IMX500_FRAME_LENGTH_MAX - IMX500_EXPOSURE_OFFSET) ++ ++/* Analog gain control */ ++#define IMX500_REG_ANALOG_GAIN CCI_REG16(0x0204) ++#define IMX500_ANA_GAIN_MIN 0 ++#define IMX500_ANA_GAIN_MAX 978 ++#define IMX500_ANA_GAIN_STEP 1 ++#define IMX500_ANA_GAIN_DEFAULT 0x0 ++ ++/* Colour balance controls */ ++#define IMX500_REG_COLOUR_BALANCE_R CCI_REG16(0xd804) ++#define IMX500_REG_COLOUR_BALANCE_GR CCI_REG16(0xd806) ++#define IMX500_REG_COLOUR_BALANCE_GB CCI_REG16(0xd808) ++#define IMX500_REG_COLOUR_BALANCE_B CCI_REG16(0xd80a) ++#define IMX500_COLOUR_BALANCE_MIN 0x0001 ++#define IMX500_COLOUR_BALANCE_MAX 0x0fff ++#define IMX500_COLOUR_BALANCE_STEP 0x0001 ++#define IMX500_COLOUR_BALANCE_DEFAULT 0x0100 ++ ++/* Embedded sizes */ ++#define IMX500_MAX_EMBEDDED_SIZE \ ++ (2 * ((((IMX500_PIXEL_ARRAY_WIDTH * 10) >> 3) + 15) & ~15)) ++ ++/* IMX500 native and active pixel array size. */ ++#define IMX500_NATIVE_WIDTH 4072U ++#define IMX500_NATIVE_HEIGHT 3176U ++#define IMX500_PIXEL_ARRAY_LEFT 8U ++#define IMX500_PIXEL_ARRAY_TOP 16U ++#define IMX500_PIXEL_ARRAY_WIDTH 4056U ++#define IMX500_PIXEL_ARRAY_HEIGHT 3040U ++ ++#define NUM_PADS 1 ++ ++/* regulator supplies */ ++static const char *const imx500_supply_name[] = { ++ /* Supplies can be enabled in any order */ ++ "vana", /* Analog (2.7V) supply */ ++ "vdig", /* Digital Core (0.84V) supply */ ++ "vif", /* Interface (1.8V) supply */ ++}; ++ ++#define IMX500_NUM_SUPPLIES ARRAY_SIZE(imx500_supply_name) ++ ++struct imx500_reg_list { ++ unsigned int num_of_regs; ++ const struct cci_reg_sequence *regs; ++}; ++ ++/* Mode : resolution and related config&values */ ++struct imx500_mode { ++ /* Frame width */ ++ unsigned int width; ++ ++ /* Frame height */ ++ unsigned int height; ++ ++ /* H-timing in pixels */ ++ unsigned int line_length_pix; ++ ++ /* Analog crop rectangle. */ ++ struct v4l2_rect crop; ++ ++ /* Default framerate. */ ++ unsigned int framerate_default; ++ ++ /* Default register values */ ++ struct imx500_reg_list reg_list; ++}; ++ ++static const struct cci_reg_sequence mode_common_regs[] = { ++ { CCI_REG8(0x0305), 0x02 }, ++ { CCI_REG8(0x0306), 0x00 }, ++ { CCI_REG8(0x030d), 0x02 }, ++ { CCI_REG8(0x030e), 0x00 }, ++ { CCI_REG8(0x0106), 0x01 }, /* FAST_STANDBY_CTL */ ++ { CCI_REG8(0x0136), 0x1b }, /* EXCLK_FREQ */ ++ { CCI_REG8(0x0137), 0x00 }, ++ { CCI_REG8(0x0138), 0x01 }, /* TEMP_SENS_CTL */ ++ { CCI_REG8(0x0112), 0x0a }, ++ { CCI_REG8(0x0113), 0x0a }, ++ { CCI_REG8(0x0114), 0x01 }, /* CSI_LANE_MODE */ ++}; ++ ++/* 12 mpix 15fps */ ++static const struct cci_reg_sequence mode_4056x3040_regs[] = { ++ { CCI_REG8(0x0340), 0x12 }, ++ { CCI_REG8(0x0341), 0x42 }, ++ { CCI_REG8(0x0342), 0x45 }, ++ { CCI_REG8(0x0343), 0xec }, ++ { CCI_REG8(0x3210), 0x00 }, ++ { CCI_REG8(0x0344), 0x00 }, ++ { CCI_REG8(0x0345), 0x00 }, ++ { CCI_REG8(0x0346), 0x00 }, ++ { CCI_REG8(0x0347), 0x00 }, ++ { CCI_REG8(0x0348), 0x0f }, ++ { CCI_REG8(0x0349), 0xd7 }, ++ { CCI_REG8(0x0350), 0x00 }, ++ { CCI_REG8(0x034a), 0x0b }, ++ { CCI_REG8(0x034b), 0xdf }, ++ { CCI_REG8(0x3f58), 0x01 }, ++ { CCI_REG8(0x0381), 0x01 }, ++ { CCI_REG8(0x0383), 0x01 }, ++ { CCI_REG8(0x0385), 0x01 }, ++ { CCI_REG8(0x0387), 0x01 }, ++ { CCI_REG8(0x0900), 0x00 }, ++ { CCI_REG8(0x0901), 0x11 }, ++ { CCI_REG8(0x0902), 0x00 }, ++ { CCI_REG8(0x3241), 0x11 }, ++ { CCI_REG8(0x3242), 0x01 }, ++ { CCI_REG8(0x3250), 0x00 }, ++ { CCI_REG8(0x3f0f), 0x00 }, ++ { CCI_REG8(0x3f40), 0x00 }, ++ { CCI_REG8(0x3f41), 0x00 }, ++ { CCI_REG8(0x3f42), 0x00 }, ++ { CCI_REG8(0x3f43), 0x00 }, ++ { CCI_REG8(0xb34e), 0x00 }, ++ { CCI_REG8(0xb351), 0x20 }, ++ { CCI_REG8(0xb35c), 0x00 }, ++ { CCI_REG8(0xb35e), 0x08 }, ++ { CCI_REG8(0x0401), 0x00 }, ++ { CCI_REG8(0x0404), 0x00 }, ++ { CCI_REG8(0x0405), 0x10 }, ++ { CCI_REG8(0x0408), 0x00 }, ++ { CCI_REG8(0x0409), 0x00 }, ++ { CCI_REG8(0x040a), 0x00 }, ++ { CCI_REG8(0x040b), 0x00 }, ++ { CCI_REG8(0x040c), 0x0f }, ++ { CCI_REG8(0x040d), 0xd8 }, ++ { CCI_REG8(0x040e), 0x0b }, ++ { CCI_REG8(0x040f), 0xe0 }, ++ { CCI_REG8(0x034c), 0x0f }, ++ { CCI_REG8(0x034d), 0xd8 }, ++ { CCI_REG8(0x034e), 0x0b }, ++ { CCI_REG8(0x034f), 0xe0 }, ++ { CCI_REG8(0x0301), 0x05 }, ++ { CCI_REG8(0x0303), 0x02 }, ++ { CCI_REG8(0x0307), 0x9b }, ++ { CCI_REG8(0x0309), 0x0a }, ++ { CCI_REG8(0x030b), 0x01 }, ++ { CCI_REG8(0x030f), 0x4a }, ++ { CCI_REG8(0x0310), 0x01 }, ++ { CCI_REG8(0x0820), 0x07 }, ++ { CCI_REG8(0x0821), 0xce }, ++ { CCI_REG8(0x0822), 0x00 }, ++ { CCI_REG8(0x0823), 0x00 }, ++ { CCI_REG8(0x3e20), 0x01 }, ++ { CCI_REG8(0x3e35), 0x01 }, ++ { CCI_REG8(0x3e36), 0x01 }, ++ { CCI_REG8(0x3e37), 0x00 }, ++ { CCI_REG8(0x3e3a), 0x01 }, ++ { CCI_REG8(0x3e3b), 0x00 }, ++ { CCI_REG8(0x00e3), 0x00 }, ++ { CCI_REG8(0x00e4), 0x00 }, ++ { CCI_REG8(0x00e6), 0x00 }, ++ { CCI_REG8(0x00e7), 0x00 }, ++ { CCI_REG8(0x00e8), 0x00 }, ++ { CCI_REG8(0x00e9), 0x00 }, ++ { CCI_REG8(0x3f50), 0x00 }, ++ { CCI_REG8(0x3f56), 0x02 }, ++ { CCI_REG8(0x3f57), 0x42 }, ++ { CCI_REG8(0x3606), 0x01 }, ++ { CCI_REG8(0x3607), 0x01 }, ++ { CCI_REG8(0x3f26), 0x00 }, ++ { CCI_REG8(0x3f4a), 0x00 }, ++ { CCI_REG8(0x3f4b), 0x00 }, ++ { CCI_REG8(0x4bc0), 0x16 }, ++ { CCI_REG8(0x7ba8), 0x00 }, ++ { CCI_REG8(0x7ba9), 0x00 }, ++ { CCI_REG8(0x886b), 0x00 }, ++ { CCI_REG8(0x579a), 0x00 }, ++ { CCI_REG8(0x579b), 0x0a }, ++ { CCI_REG8(0x579c), 0x01 }, ++ { CCI_REG8(0x579d), 0x2a }, ++ { CCI_REG8(0x57ac), 0x00 }, ++ { CCI_REG8(0x57ad), 0x00 }, ++ { CCI_REG8(0x57ae), 0x00 }, ++ { CCI_REG8(0x57af), 0x81 }, ++ { CCI_REG8(0x57be), 0x00 }, ++ { CCI_REG8(0x57bf), 0x00 }, ++ { CCI_REG8(0x57c0), 0x00 }, ++ { CCI_REG8(0x57c1), 0x81 }, ++ { CCI_REG8(0x57d0), 0x00 }, ++ { CCI_REG8(0x57d1), 0x00 }, ++ { CCI_REG8(0x57d2), 0x00 }, ++ { CCI_REG8(0x57d3), 0x81 }, ++ { CCI_REG8(0x5324), 0x00 }, ++ { CCI_REG8(0x5325), 0x26 }, ++ { CCI_REG8(0x5326), 0x00 }, ++ { CCI_REG8(0x5327), 0x6b }, ++ { CCI_REG8(0xbca7), 0x00 }, ++ { CCI_REG8(0x5fcc), 0x28 }, ++ { CCI_REG8(0x5fd7), 0x2d }, ++ { CCI_REG8(0x5fe2), 0x2d }, ++ { CCI_REG8(0x5fed), 0x2d }, ++ { CCI_REG8(0x5ff8), 0x2d }, ++ { CCI_REG8(0x6003), 0x2d }, ++ { CCI_REG8(0x5d0b), 0x01 }, ++ { CCI_REG8(0x6f6d), 0x00 }, ++ { CCI_REG8(0x61c9), 0x00 }, ++ { CCI_REG8(0x5352), 0x00 }, ++ { CCI_REG8(0x5353), 0x49 }, ++ { CCI_REG8(0x5356), 0x00 }, ++ { CCI_REG8(0x5357), 0x30 }, ++ { CCI_REG8(0x5358), 0x00 }, ++ { CCI_REG8(0x5359), 0x3b }, ++ { CCI_REG8(0x535c), 0x00 }, ++ { CCI_REG8(0x535d), 0xb0 }, ++ { CCI_REG8(0x6187), 0x18 }, ++ { CCI_REG8(0x6189), 0x18 }, ++ { CCI_REG8(0x618b), 0x18 }, ++ { CCI_REG8(0x618d), 0x1d }, ++ { CCI_REG8(0x618f), 0x1d }, ++ { CCI_REG8(0x5414), 0x01 }, ++ { CCI_REG8(0x5415), 0x0c }, ++ { CCI_REG8(0xbca8), 0x0a }, ++ { CCI_REG8(0x5fcf), 0x1e }, ++ { CCI_REG8(0x5fda), 0x1e }, ++ { CCI_REG8(0x5fe5), 0x1e }, ++ { CCI_REG8(0x5ff0), 0x1e }, ++ { CCI_REG8(0x5ffb), 0x1e }, ++ { CCI_REG8(0x6006), 0x1e }, ++ { CCI_REG8(0x616e), 0x04 }, ++ { CCI_REG8(0x616f), 0x04 }, ++ { CCI_REG8(0x6170), 0x04 }, ++ { CCI_REG8(0x6171), 0x06 }, ++ { CCI_REG8(0x6172), 0x06 }, ++ { CCI_REG8(0x6173), 0x0c }, ++ { CCI_REG8(0x6174), 0x0c }, ++ { CCI_REG8(0x6175), 0x0c }, ++ { CCI_REG8(0x6176), 0x00 }, ++ { CCI_REG8(0x6177), 0x10 }, ++ { CCI_REG8(0x6178), 0x00 }, ++ { CCI_REG8(0x6179), 0x1a }, ++ { CCI_REG8(0x617a), 0x00 }, ++ { CCI_REG8(0x617b), 0x1a }, ++ { CCI_REG8(0x617c), 0x00 }, ++ { CCI_REG8(0x617d), 0x27 }, ++ { CCI_REG8(0x617e), 0x00 }, ++ { CCI_REG8(0x617f), 0x27 }, ++ { CCI_REG8(0x6180), 0x00 }, ++ { CCI_REG8(0x6181), 0x44 }, ++ { CCI_REG8(0x6182), 0x00 }, ++ { CCI_REG8(0x6183), 0x44 }, ++ { CCI_REG8(0x6184), 0x00 }, ++ { CCI_REG8(0x6185), 0x44 }, ++ { CCI_REG8(0x5dfc), 0x0a }, ++ { CCI_REG8(0x5e00), 0x0a }, ++ { CCI_REG8(0x5e04), 0x0a }, ++ { CCI_REG8(0x5e08), 0x0a }, ++ { CCI_REG8(0x5dfd), 0x0a }, ++ { CCI_REG8(0x5e01), 0x0a }, ++ { CCI_REG8(0x5e05), 0x0a }, ++ { CCI_REG8(0x5e09), 0x0a }, ++ { CCI_REG8(0x5dfe), 0x0a }, ++ { CCI_REG8(0x5e02), 0x0a }, ++ { CCI_REG8(0x5e06), 0x0a }, ++ { CCI_REG8(0x5e0a), 0x0a }, ++ { CCI_REG8(0x5dff), 0x0a }, ++ { CCI_REG8(0x5e03), 0x0a }, ++ { CCI_REG8(0x5e07), 0x0a }, ++ { CCI_REG8(0x5e0b), 0x0a }, ++ { CCI_REG8(0x5dec), 0x12 }, ++ { CCI_REG8(0x5df0), 0x12 }, ++ { CCI_REG8(0x5df4), 0x21 }, ++ { CCI_REG8(0x5df8), 0x31 }, ++ { CCI_REG8(0x5ded), 0x12 }, ++ { CCI_REG8(0x5df1), 0x12 }, ++ { CCI_REG8(0x5df5), 0x21 }, ++ { CCI_REG8(0x5df9), 0x31 }, ++ { CCI_REG8(0x5dee), 0x12 }, ++ { CCI_REG8(0x5df2), 0x12 }, ++ { CCI_REG8(0x5df6), 0x21 }, ++ { CCI_REG8(0x5dfa), 0x31 }, ++ { CCI_REG8(0x5def), 0x12 }, ++ { CCI_REG8(0x5df3), 0x12 }, ++ { CCI_REG8(0x5df7), 0x21 }, ++ { CCI_REG8(0x5dfb), 0x31 }, ++ { CCI_REG8(0x5ddc), 0x0d }, ++ { CCI_REG8(0x5de0), 0x0d }, ++ { CCI_REG8(0x5de4), 0x0d }, ++ { CCI_REG8(0x5de8), 0x0d }, ++ { CCI_REG8(0x5ddd), 0x0d }, ++ { CCI_REG8(0x5de1), 0x0d }, ++ { CCI_REG8(0x5de5), 0x0d }, ++ { CCI_REG8(0x5de9), 0x0d }, ++ { CCI_REG8(0x5dde), 0x0d }, ++ { CCI_REG8(0x5de2), 0x0d }, ++ { CCI_REG8(0x5de6), 0x0d }, ++ { CCI_REG8(0x5dea), 0x0d }, ++ { CCI_REG8(0x5ddf), 0x0d }, ++ { CCI_REG8(0x5de3), 0x0d }, ++ { CCI_REG8(0x5de7), 0x0d }, ++ { CCI_REG8(0x5deb), 0x0d }, ++ { CCI_REG8(0x5dcc), 0x55 }, ++ { CCI_REG8(0x5dd0), 0x50 }, ++ { CCI_REG8(0x5dd4), 0x4b }, ++ { CCI_REG8(0x5dd8), 0x4b }, ++ { CCI_REG8(0x5dcd), 0x55 }, ++ { CCI_REG8(0x5dd1), 0x50 }, ++ { CCI_REG8(0x5dd5), 0x4b }, ++ { CCI_REG8(0x5dd9), 0x4b }, ++ { CCI_REG8(0x5dce), 0x55 }, ++ { CCI_REG8(0x5dd2), 0x50 }, ++ { CCI_REG8(0x5dd6), 0x4b }, ++ { CCI_REG8(0x5dda), 0x4b }, ++ { CCI_REG8(0x5dcf), 0x55 }, ++ { CCI_REG8(0x5dd3), 0x50 }, ++ { CCI_REG8(0x5dd7), 0x4b }, ++ { CCI_REG8(0x5ddb), 0x4b }, ++ { CCI_REG8(0x0202), 0x12 }, ++ { CCI_REG8(0x0203), 0x2c }, ++ { CCI_REG8(0x0204), 0x00 }, ++ { CCI_REG8(0x0205), 0x00 }, ++ { CCI_REG8(0x020e), 0x01 }, ++ { CCI_REG8(0x020f), 0x00 }, ++ { CCI_REG8(0x0210), 0x01 }, ++ { CCI_REG8(0x0211), 0x00 }, ++ { CCI_REG8(0x0212), 0x01 }, ++ { CCI_REG8(0x0213), 0x00 }, ++ { CCI_REG8(0x0214), 0x01 }, ++ { CCI_REG8(0x0215), 0x00 }, ++}; ++ ++/* 2x2 binned. 56fps */ ++static const struct cci_reg_sequence mode_2028x1520_regs[] = { ++ { CCI_REG8(0x0112), 0x0a }, ++ { CCI_REG8(0x0113), 0x0a }, ++ { CCI_REG8(0x0114), 0x01 }, ++ { CCI_REG8(0x0342), 0x24 }, ++ { CCI_REG8(0x0343), 0xb6 }, ++ { CCI_REG8(0x0340), 0x0b }, ++ { CCI_REG8(0x0341), 0x9c }, ++ { CCI_REG8(0x3210), 0x00 }, ++ { CCI_REG8(0x0344), 0x00 }, ++ { CCI_REG8(0x0345), 0x00 }, ++ { CCI_REG8(0x0346), 0x00 }, ++ { CCI_REG8(0x0347), 0x00 }, ++ { CCI_REG8(0x0348), 0x0f }, ++ { CCI_REG8(0x0349), 0xd7 }, ++ { CCI_REG8(0x0350), 0x00 }, ++ { CCI_REG8(0x034a), 0x0b }, ++ { CCI_REG8(0x034b), 0xdf }, ++ { CCI_REG8(0x3f58), 0x01 }, ++ { CCI_REG8(0x0381), 0x01 }, ++ { CCI_REG8(0x0383), 0x01 }, ++ { CCI_REG8(0x0385), 0x01 }, ++ { CCI_REG8(0x0387), 0x01 }, ++ { CCI_REG8(0x0900), 0x01 }, ++ { CCI_REG8(0x0901), 0x22 }, ++ { CCI_REG8(0x0902), 0x02 }, ++ { CCI_REG8(0x3241), 0x11 }, ++ { CCI_REG8(0x3242), 0x01 }, ++ { CCI_REG8(0x3250), 0x03 }, ++ { CCI_REG8(0x3f0f), 0x00 }, ++ { CCI_REG8(0x3f40), 0x00 }, ++ { CCI_REG8(0x3f41), 0x00 }, ++ { CCI_REG8(0x3f42), 0x00 }, ++ { CCI_REG8(0x3f43), 0x00 }, ++ { CCI_REG8(0xb34e), 0x00 }, ++ { CCI_REG8(0xb351), 0x20 }, ++ { CCI_REG8(0xb35c), 0x00 }, ++ { CCI_REG8(0xb35e), 0x08 }, ++ { CCI_REG8(0x0401), 0x00 }, ++ { CCI_REG8(0x0404), 0x00 }, ++ { CCI_REG8(0x0405), 0x10 }, ++ { CCI_REG8(0x0408), 0x00 }, ++ { CCI_REG8(0x0409), 0x00 }, ++ { CCI_REG8(0x040a), 0x00 }, ++ { CCI_REG8(0x040b), 0x00 }, ++ { CCI_REG8(0x040c), 0x07 }, ++ { CCI_REG8(0x040d), 0xec }, ++ { CCI_REG8(0x040e), 0x05 }, ++ { CCI_REG8(0x040f), 0xf0 }, ++ { CCI_REG8(0x034c), 0x07 }, ++ { CCI_REG8(0x034d), 0xec }, ++ { CCI_REG8(0x034e), 0x05 }, ++ { CCI_REG8(0x034f), 0xf0 }, ++ { CCI_REG8(0x0301), 0x05 }, ++ { CCI_REG8(0x0303), 0x02 }, ++ { CCI_REG8(0x0307), 0x9b }, ++ { CCI_REG8(0x0309), 0x0a }, ++ { CCI_REG8(0x030b), 0x01 }, ++ { CCI_REG8(0x030f), 0x4a }, ++ { CCI_REG8(0x0310), 0x01 }, ++ { CCI_REG8(0x0820), 0x07 }, ++ { CCI_REG8(0x0821), 0xce }, ++ { CCI_REG8(0x0822), 0x00 }, ++ { CCI_REG8(0x0823), 0x00 }, ++ { CCI_REG8(0x3e20), 0x01 }, ++ { CCI_REG8(0x3e35), 0x01 }, ++ { CCI_REG8(0x3e36), 0x01 }, ++ { CCI_REG8(0x3e37), 0x00 }, ++ { CCI_REG8(0x3e3a), 0x01 }, ++ { CCI_REG8(0x3e3b), 0x00 }, ++ { CCI_REG8(0x00e3), 0x00 }, ++ { CCI_REG8(0x00e4), 0x00 }, ++ { CCI_REG8(0x00e6), 0x00 }, ++ { CCI_REG8(0x00e7), 0x00 }, ++ { CCI_REG8(0x00e8), 0x00 }, ++ { CCI_REG8(0x00e9), 0x00 }, ++ { CCI_REG8(0x3f50), 0x00 }, ++ { CCI_REG8(0x3f56), 0x01 }, ++ { CCI_REG8(0x3f57), 0x30 }, ++ { CCI_REG8(0x3606), 0x01 }, ++ { CCI_REG8(0x3607), 0x01 }, ++ { CCI_REG8(0x3f26), 0x00 }, ++ { CCI_REG8(0x3f4a), 0x00 }, ++ { CCI_REG8(0x3f4b), 0x00 }, ++ { CCI_REG8(0x4bc0), 0x16 }, ++ { CCI_REG8(0x7ba8), 0x00 }, ++ { CCI_REG8(0x7ba9), 0x00 }, ++ { CCI_REG8(0x886b), 0x00 }, ++ { CCI_REG8(0x579a), 0x00 }, ++ { CCI_REG8(0x579b), 0x0a }, ++ { CCI_REG8(0x579c), 0x01 }, ++ { CCI_REG8(0x579d), 0x2a }, ++ { CCI_REG8(0x57ac), 0x00 }, ++ { CCI_REG8(0x57ad), 0x00 }, ++ { CCI_REG8(0x57ae), 0x00 }, ++ { CCI_REG8(0x57af), 0x81 }, ++ { CCI_REG8(0x57be), 0x00 }, ++ { CCI_REG8(0x57bf), 0x00 }, ++ { CCI_REG8(0x57c0), 0x00 }, ++ { CCI_REG8(0x57c1), 0x81 }, ++ { CCI_REG8(0x57d0), 0x00 }, ++ { CCI_REG8(0x57d1), 0x00 }, ++ { CCI_REG8(0x57d2), 0x00 }, ++ { CCI_REG8(0x57d3), 0x81 }, ++ { CCI_REG8(0x5324), 0x00 }, ++ { CCI_REG8(0x5325), 0x31 }, ++ { CCI_REG8(0x5326), 0x00 }, ++ { CCI_REG8(0x5327), 0x60 }, ++ { CCI_REG8(0xbca7), 0x08 }, ++ { CCI_REG8(0x5fcc), 0x1e }, ++ { CCI_REG8(0x5fd7), 0x1e }, ++ { CCI_REG8(0x5fe2), 0x1e }, ++ { CCI_REG8(0x5fed), 0x1e }, ++ { CCI_REG8(0x5ff8), 0x1e }, ++ { CCI_REG8(0x6003), 0x1e }, ++ { CCI_REG8(0x5d0b), 0x02 }, ++ { CCI_REG8(0x6f6d), 0x01 }, ++ { CCI_REG8(0x61c9), 0x68 }, ++ { CCI_REG8(0x5352), 0x00 }, ++ { CCI_REG8(0x5353), 0x3f }, ++ { CCI_REG8(0x5356), 0x00 }, ++ { CCI_REG8(0x5357), 0x1c }, ++ { CCI_REG8(0x5358), 0x00 }, ++ { CCI_REG8(0x5359), 0x3d }, ++ { CCI_REG8(0x535c), 0x00 }, ++ { CCI_REG8(0x535d), 0xa6 }, ++ { CCI_REG8(0x6187), 0x1d }, ++ { CCI_REG8(0x6189), 0x1d }, ++ { CCI_REG8(0x618b), 0x1d }, ++ { CCI_REG8(0x618d), 0x23 }, ++ { CCI_REG8(0x618f), 0x23 }, ++ { CCI_REG8(0x5414), 0x01 }, ++ { CCI_REG8(0x5415), 0x12 }, ++ { CCI_REG8(0xbca8), 0x00 }, ++ { CCI_REG8(0x5fcf), 0x28 }, ++ { CCI_REG8(0x5fda), 0x2d }, ++ { CCI_REG8(0x5fe5), 0x2d }, ++ { CCI_REG8(0x5ff0), 0x2d }, ++ { CCI_REG8(0x5ffb), 0x2d }, ++ { CCI_REG8(0x6006), 0x2d }, ++ { CCI_REG8(0x616e), 0x04 }, ++ { CCI_REG8(0x616f), 0x04 }, ++ { CCI_REG8(0x6170), 0x04 }, ++ { CCI_REG8(0x6171), 0x06 }, ++ { CCI_REG8(0x6172), 0x06 }, ++ { CCI_REG8(0x6173), 0x0c }, ++ { CCI_REG8(0x6174), 0x0c }, ++ { CCI_REG8(0x6175), 0x0c }, ++ { CCI_REG8(0x6176), 0x00 }, ++ { CCI_REG8(0x6177), 0x10 }, ++ { CCI_REG8(0x6178), 0x00 }, ++ { CCI_REG8(0x6179), 0x1a }, ++ { CCI_REG8(0x617a), 0x00 }, ++ { CCI_REG8(0x617b), 0x1a }, ++ { CCI_REG8(0x617c), 0x00 }, ++ { CCI_REG8(0x617d), 0x27 }, ++ { CCI_REG8(0x617e), 0x00 }, ++ { CCI_REG8(0x617f), 0x27 }, ++ { CCI_REG8(0x6180), 0x00 }, ++ { CCI_REG8(0x6181), 0x44 }, ++ { CCI_REG8(0x6182), 0x00 }, ++ { CCI_REG8(0x6183), 0x44 }, ++ { CCI_REG8(0x6184), 0x00 }, ++ { CCI_REG8(0x6185), 0x44 }, ++ { CCI_REG8(0x5dfc), 0x0a }, ++ { CCI_REG8(0x5e00), 0x0a }, ++ { CCI_REG8(0x5e04), 0x0a }, ++ { CCI_REG8(0x5e08), 0x0a }, ++ { CCI_REG8(0x5dfd), 0x0a }, ++ { CCI_REG8(0x5e01), 0x0a }, ++ { CCI_REG8(0x5e05), 0x0a }, ++ { CCI_REG8(0x5e09), 0x0a }, ++ { CCI_REG8(0x5dfe), 0x0a }, ++ { CCI_REG8(0x5e02), 0x0a }, ++ { CCI_REG8(0x5e06), 0x0a }, ++ { CCI_REG8(0x5e0a), 0x0a }, ++ { CCI_REG8(0x5dff), 0x0a }, ++ { CCI_REG8(0x5e03), 0x0a }, ++ { CCI_REG8(0x5e07), 0x0a }, ++ { CCI_REG8(0x5e0b), 0x0a }, ++ { CCI_REG8(0x5dec), 0x12 }, ++ { CCI_REG8(0x5df0), 0x12 }, ++ { CCI_REG8(0x5df4), 0x21 }, ++ { CCI_REG8(0x5df8), 0x31 }, ++ { CCI_REG8(0x5ded), 0x12 }, ++ { CCI_REG8(0x5df1), 0x12 }, ++ { CCI_REG8(0x5df5), 0x21 }, ++ { CCI_REG8(0x5df9), 0x31 }, ++ { CCI_REG8(0x5dee), 0x12 }, ++ { CCI_REG8(0x5df2), 0x12 }, ++ { CCI_REG8(0x5df6), 0x21 }, ++ { CCI_REG8(0x5dfa), 0x31 }, ++ { CCI_REG8(0x5def), 0x12 }, ++ { CCI_REG8(0x5df3), 0x12 }, ++ { CCI_REG8(0x5df7), 0x21 }, ++ { CCI_REG8(0x5dfb), 0x31 }, ++ { CCI_REG8(0x5ddc), 0x0d }, ++ { CCI_REG8(0x5de0), 0x0d }, ++ { CCI_REG8(0x5de4), 0x0d }, ++ { CCI_REG8(0x5de8), 0x0d }, ++ { CCI_REG8(0x5ddd), 0x0d }, ++ { CCI_REG8(0x5de1), 0x0d }, ++ { CCI_REG8(0x5de5), 0x0d }, ++ { CCI_REG8(0x5de9), 0x0d }, ++ { CCI_REG8(0x5dde), 0x0d }, ++ { CCI_REG8(0x5de2), 0x0d }, ++ { CCI_REG8(0x5de6), 0x0d }, ++ { CCI_REG8(0x5dea), 0x0d }, ++ { CCI_REG8(0x5ddf), 0x0d }, ++ { CCI_REG8(0x5de3), 0x0d }, ++ { CCI_REG8(0x5de7), 0x0d }, ++ { CCI_REG8(0x5deb), 0x0d }, ++ { CCI_REG8(0x5dcc), 0x55 }, ++ { CCI_REG8(0x5dd0), 0x50 }, ++ { CCI_REG8(0x5dd4), 0x4b }, ++ { CCI_REG8(0x5dd8), 0x4b }, ++ { CCI_REG8(0x5dcd), 0x55 }, ++ { CCI_REG8(0x5dd1), 0x50 }, ++ { CCI_REG8(0x5dd5), 0x4b }, ++ { CCI_REG8(0x5dd9), 0x4b }, ++ { CCI_REG8(0x5dce), 0x55 }, ++ { CCI_REG8(0x5dd2), 0x50 }, ++ { CCI_REG8(0x5dd6), 0x4b }, ++ { CCI_REG8(0x5dda), 0x4b }, ++ { CCI_REG8(0x5dcf), 0x55 }, ++ { CCI_REG8(0x5dd3), 0x50 }, ++ { CCI_REG8(0x5dd7), 0x4b }, ++ { CCI_REG8(0x5ddb), 0x4b }, ++ { CCI_REG8(0x0202), 0x0b }, ++ { CCI_REG8(0x0203), 0x86 }, ++ { CCI_REG8(0x0204), 0x00 }, ++ { CCI_REG8(0x0205), 0x00 }, ++ { CCI_REG8(0x020e), 0x01 }, ++ { CCI_REG8(0x020f), 0x00 }, ++ { CCI_REG8(0x0210), 0x01 }, ++ { CCI_REG8(0x0211), 0x00 }, ++ { CCI_REG8(0x0212), 0x01 }, ++ { CCI_REG8(0x0213), 0x00 }, ++ { CCI_REG8(0x0214), 0x01 }, ++ { CCI_REG8(0x0215), 0x00 }, ++}; ++ ++/* Mode configs */ ++static const struct imx500_mode imx500_supported_modes[] = { ++ { ++ /* 12MPix 10fps mode */ ++ .width = 4056, ++ .height = 3040, ++ .line_length_pix = 17900, ++ .crop = { ++ .left = IMX500_PIXEL_ARRAY_LEFT, ++ .top = IMX500_PIXEL_ARRAY_TOP, ++ .width = 4056, ++ .height = 3040, ++ }, ++ .framerate_default = 10, ++ .reg_list = { ++ .num_of_regs = ARRAY_SIZE(mode_4056x3040_regs), ++ .regs = mode_4056x3040_regs, ++ }, ++ }, ++ { ++ /* 2x2 binned 40fps mode */ ++ .width = 2028, ++ .height = 1520, ++ .line_length_pix = 9398, ++ .crop = { ++ .left = IMX500_PIXEL_ARRAY_LEFT, ++ .top = IMX500_PIXEL_ARRAY_TOP, ++ .width = 4056, ++ .height = 3040, ++ }, ++ .framerate_default = 40, ++ .reg_list = { ++ .num_of_regs = ARRAY_SIZE(mode_2028x1520_regs), ++ .regs = mode_2028x1520_regs, ++ }, ++ }, ++}; ++ ++/* ++ * The supported formats. ++ * This table MUST contain 4 entries per format, to cover the various flip ++ * combinations in the order ++ * - no flip ++ * - h flip ++ * - v flip ++ * - h&v flips ++ */ ++static const u32 codes[] = { ++ /* 10-bit modes. */ ++ MEDIA_BUS_FMT_SRGGB10_1X10, ++ MEDIA_BUS_FMT_SGRBG10_1X10, ++ MEDIA_BUS_FMT_SGBRG10_1X10, ++ MEDIA_BUS_FMT_SBGGR10_1X10, ++}; ++ ++struct imx500 { ++ struct v4l2_subdev sd; ++ struct media_pad pad; ++ struct regmap *regmap; ++ ++ unsigned int fmt_code; ++ ++ struct clk *xclk; ++ u32 xclk_freq; ++ ++ struct gpio_desc *reset_gpio; ++ struct regulator_bulk_data supplies[IMX500_NUM_SUPPLIES]; ++ ++ struct v4l2_ctrl_handler ctrl_handler; ++ /* V4L2 Controls */ ++ struct v4l2_ctrl *pixel_rate; ++ struct v4l2_ctrl *link_freq; ++ struct v4l2_ctrl *exposure; ++ struct v4l2_ctrl *vflip; ++ struct v4l2_ctrl *hflip; ++ struct v4l2_ctrl *vblank; ++ struct v4l2_ctrl *hblank; ++ ++ /* Current mode */ ++ const struct imx500_mode *mode; ++ ++ /* ++ * Mutex for serialized access: ++ * Protect sensor module set pad format and start/stop streaming safely. ++ */ ++ struct mutex mutex; ++ ++ /* Streaming on/off */ ++ bool streaming; ++ ++ /* Rewrite common registers on stream on? */ ++ bool common_regs_written; ++ ++ /* Current long exposure factor in use. Set through V4L2_CID_VBLANK */ ++ unsigned int long_exp_shift; ++}; ++ ++static inline struct imx500 *to_imx500(struct v4l2_subdev *_sd) ++{ ++ return container_of(_sd, struct imx500, sd); ++} ++ ++/* Get bayer order based on flip setting. */ ++static u32 imx500_get_format_code(struct imx500 *imx500) ++{ ++ unsigned int i; ++ ++ lockdep_assert_held(&imx500->mutex); ++ ++ i = (imx500->vflip->val ? 2 : 0) | (imx500->hflip->val ? 1 : 0); ++ ++ return codes[i]; ++} ++ ++static void imx500_set_default_format(struct imx500 *imx500) ++{ ++ /* Set default mode to max resolution */ ++ imx500->mode = &imx500_supported_modes[0]; ++ imx500->fmt_code = MEDIA_BUS_FMT_SRGGB10_1X10; ++} ++ ++static void imx500_adjust_exposure_range(struct imx500 *imx500) ++{ ++ int exposure_max, exposure_def; ++ ++ /* Honour the VBLANK limits when setting exposure. */ ++ exposure_max = imx500->mode->height + imx500->vblank->val - ++ IMX500_EXPOSURE_OFFSET; ++ exposure_def = min(exposure_max, imx500->exposure->val); ++ __v4l2_ctrl_modify_range(imx500->exposure, imx500->exposure->minimum, ++ exposure_max, imx500->exposure->step, ++ exposure_def); ++} ++ ++static int imx500_set_frame_length(struct imx500 *imx500, unsigned int val) ++{ ++ int ret = 0; ++ ++ imx500->long_exp_shift = 0; ++ ++ while (val > IMX500_FRAME_LENGTH_MAX) { ++ imx500->long_exp_shift++; ++ val >>= 1; ++ } ++ ++ ret = cci_write(imx500->regmap, IMX500_REG_FRAME_LENGTH, val, NULL); ++ if (ret) ++ return ret; ++ ++ return cci_write(imx500->regmap, IMX500_LONG_EXP_SHIFT_REG, ++ imx500->long_exp_shift, NULL); ++} ++ ++static int imx500_set_ctrl(struct v4l2_ctrl *ctrl) ++{ ++ struct imx500 *imx500 = ++ container_of(ctrl->handler, struct imx500, ctrl_handler); ++ struct i2c_client *client = v4l2_get_subdevdata(&imx500->sd); ++ int ret = 0; ++ ++ /* ++ * The VBLANK control may change the limits of usable exposure, so check ++ * and adjust if necessary. ++ */ ++ if (ctrl->id == V4L2_CID_VBLANK) ++ imx500_adjust_exposure_range(imx500); ++ ++ /* ++ * Applying V4L2 control value only happens ++ * when power is up for streaming ++ */ ++ if (pm_runtime_get_if_in_use(&client->dev) == 0) ++ return 0; ++ ++ switch (ctrl->id) { ++ case V4L2_CID_ANALOGUE_GAIN: ++ ret = cci_write(imx500->regmap, IMX500_REG_ANALOG_GAIN, ++ ctrl->val, NULL); ++ break; ++ case V4L2_CID_EXPOSURE: ++ ret = cci_write(imx500->regmap, IMX500_REG_EXPOSURE, ++ ctrl->val >> imx500->long_exp_shift, NULL); ++ break; ++ case V4L2_CID_HFLIP: ++ case V4L2_CID_VFLIP: ++ ret = cci_write(imx500->regmap, IMX500_REG_ORIENTATION, ++ imx500->hflip->val | imx500->vflip->val << 1, ++ NULL); ++ break; ++ case V4L2_CID_VBLANK: ++ ret = imx500_set_frame_length(imx500, ++ imx500->mode->height + ctrl->val); ++ break; ++ case V4L2_CID_HBLANK: ++ ret = cci_write(imx500->regmap, IMX500_REG_LINE_LENGTH, ++ imx500->mode->width + ctrl->val, NULL); ++ break; ++ case V4L2_CID_NOTIFY_GAINS: ++ ret = cci_write(imx500->regmap, IMX500_REG_COLOUR_BALANCE_B, ++ ctrl->p_new.p_u32[0], NULL); ++ cci_write(imx500->regmap, IMX500_REG_COLOUR_BALANCE_GB, ++ ctrl->p_new.p_u32[1], &ret); ++ cci_write(imx500->regmap, IMX500_REG_COLOUR_BALANCE_GR, ++ ctrl->p_new.p_u32[2], &ret); ++ cci_write(imx500->regmap, IMX500_REG_COLOUR_BALANCE_R, ++ ctrl->p_new.p_u32[3], &ret); ++ break; ++ default: ++ dev_info(&client->dev, ++ "ctrl(id:0x%x,val:0x%x) is not handled\n", ctrl->id, ++ ctrl->val); ++ ret = -EINVAL; ++ break; ++ } ++ ++ pm_runtime_mark_last_busy(&client->dev); ++ pm_runtime_put_autosuspend(&client->dev); ++ ++ return ret; ++} ++ ++static const struct v4l2_ctrl_ops imx500_ctrl_ops = { ++ .s_ctrl = imx500_set_ctrl, ++}; ++ ++static const struct v4l2_ctrl_config imx500_notify_gains_ctrl = { ++ .ops = &imx500_ctrl_ops, ++ .id = V4L2_CID_NOTIFY_GAINS, ++ .type = V4L2_CTRL_TYPE_U32, ++ .min = IMX500_COLOUR_BALANCE_MIN, ++ .max = IMX500_COLOUR_BALANCE_MAX, ++ .step = IMX500_COLOUR_BALANCE_STEP, ++ .def = IMX500_COLOUR_BALANCE_DEFAULT, ++ .dims = { 4 }, ++ .elem_size = sizeof(u32), ++}; ++ ++static int imx500_enum_mbus_code(struct v4l2_subdev *sd, ++ struct v4l2_subdev_state *sd_state, ++ struct v4l2_subdev_mbus_code_enum *code) ++{ ++ struct imx500 *imx500 = to_imx500(sd); ++ ++ if (code->pad >= NUM_PADS) ++ return -EINVAL; ++ ++ if (code->index != 0) ++ return -EINVAL; ++ ++ code->code = imx500_get_format_code(imx500); ++ ++ return 0; ++} ++ ++static int imx500_enum_frame_size(struct v4l2_subdev *sd, ++ struct v4l2_subdev_state *sd_state, ++ struct v4l2_subdev_frame_size_enum *fse) ++{ ++ struct imx500 *imx500 = to_imx500(sd); ++ ++ if (fse->pad >= NUM_PADS) ++ return -EINVAL; ++ ++ const struct imx500_mode *mode_list = imx500_supported_modes; ++ unsigned int num_modes = ARRAY_SIZE(imx500_supported_modes); ++ ++ if (fse->index >= num_modes) ++ return -EINVAL; ++ ++ if (fse->code != imx500_get_format_code(imx500)) ++ return -EINVAL; ++ ++ fse->min_width = mode_list[fse->index].width; ++ fse->max_width = fse->min_width; ++ fse->min_height = mode_list[fse->index].height; ++ fse->max_height = fse->min_height; ++ ++ return 0; ++} ++ ++static void imx500_update_image_pad_format(struct imx500 *imx500, ++ const struct imx500_mode *mode, ++ struct v4l2_subdev_format *fmt) ++{ ++ fmt->format.width = mode->width; ++ fmt->format.height = mode->height; ++ fmt->format.field = V4L2_FIELD_NONE; ++ fmt->format.colorspace = V4L2_COLORSPACE_RAW; ++ fmt->format.ycbcr_enc = ++ V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->format.colorspace); ++ fmt->format.quantization = V4L2_MAP_QUANTIZATION_DEFAULT( ++ true, fmt->format.colorspace, fmt->format.ycbcr_enc); ++ fmt->format.xfer_func = ++ V4L2_MAP_XFER_FUNC_DEFAULT(fmt->format.colorspace); ++} ++ ++static int imx500_get_pad_format(struct v4l2_subdev *sd, ++ struct v4l2_subdev_state *sd_state, ++ struct v4l2_subdev_format *fmt) ++{ ++ struct imx500 *imx500 = to_imx500(sd); ++ ++ if (fmt->pad >= NUM_PADS) ++ return -EINVAL; ++ ++ mutex_lock(&imx500->mutex); ++ ++ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { ++ struct v4l2_mbus_framefmt *try_fmt = v4l2_subdev_get_try_format( ++ &imx500->sd, sd_state, fmt->pad); ++ /* update the code which could change due to vflip or hflip */ ++ try_fmt->code = imx500_get_format_code(imx500); ++ fmt->format = *try_fmt; ++ } else { ++ imx500_update_image_pad_format(imx500, imx500->mode, fmt); ++ fmt->format.code = imx500_get_format_code(imx500); ++ } ++ ++ mutex_unlock(&imx500->mutex); ++ return 0; ++} ++ ++static unsigned int imx500_get_frame_length(const struct imx500_mode *mode, ++ unsigned int framerate_default) ++{ ++ u64 frame_length; ++ ++ frame_length = IMX500_PIXEL_RATE; ++ do_div(frame_length, (u64)framerate_default * mode->line_length_pix); ++ ++ if (WARN_ON(frame_length > IMX500_FRAME_LENGTH_MAX)) ++ frame_length = IMX500_FRAME_LENGTH_MAX; ++ ++ return max_t(unsigned int, frame_length, mode->height); ++} ++ ++static void imx500_set_framing_limits(struct imx500 *imx500) ++{ ++ unsigned int frm_length_default, hblank_min; ++ const struct imx500_mode *mode = imx500->mode; ++ ++ frm_length_default = ++ imx500_get_frame_length(mode, mode->framerate_default); ++ ++ /* Default to no long exposure multiplier. */ ++ imx500->long_exp_shift = 0; ++ ++ /* Update limits and set FPS to default */ ++ __v4l2_ctrl_modify_range( ++ imx500->vblank, 1, ++ ((1 << IMX500_LONG_EXP_SHIFT_MAX) * IMX500_FRAME_LENGTH_MAX) - ++ mode->height, ++ IMX500_VBLANK_MIN, frm_length_default - mode->height); ++ ++ /* Setting this will adjust the exposure limits as well. */ ++ __v4l2_ctrl_s_ctrl(imx500->vblank, frm_length_default - mode->height); ++ ++ hblank_min = mode->line_length_pix - mode->width; ++ __v4l2_ctrl_modify_range(imx500->hblank, hblank_min, hblank_min, 1, ++ hblank_min); ++ __v4l2_ctrl_s_ctrl(imx500->hblank, hblank_min); ++} ++ ++static int imx500_set_pad_format(struct v4l2_subdev *sd, ++ struct v4l2_subdev_state *sd_state, ++ struct v4l2_subdev_format *fmt) ++{ ++ struct v4l2_mbus_framefmt *framefmt; ++ const struct imx500_mode *mode; ++ struct imx500 *imx500 = to_imx500(sd); ++ ++ if (fmt->pad >= NUM_PADS) ++ return -EINVAL; ++ ++ mutex_lock(&imx500->mutex); ++ ++ const struct imx500_mode *mode_list = imx500_supported_modes; ++ unsigned int num_modes = ARRAY_SIZE(imx500_supported_modes); ++ ++ /* Bayer order varies with flips */ ++ fmt->format.code = imx500_get_format_code(imx500); ++ ++ mode = v4l2_find_nearest_size(mode_list, num_modes, width, height, ++ fmt->format.width, fmt->format.height); ++ imx500_update_image_pad_format(imx500, mode, fmt); ++ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { ++ framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); ++ *framefmt = fmt->format; ++ } else if (imx500->mode != mode) { ++ imx500->mode = mode; ++ imx500->fmt_code = fmt->format.code; ++ imx500_set_framing_limits(imx500); ++ } ++ ++ mutex_unlock(&imx500->mutex); ++ ++ return 0; ++} ++ ++static const struct v4l2_rect * ++__imx500_get_pad_crop(struct imx500 *imx500, struct v4l2_subdev_state *sd_state, ++ unsigned int pad, enum v4l2_subdev_format_whence which) ++{ ++ switch (which) { ++ case V4L2_SUBDEV_FORMAT_TRY: ++ return v4l2_subdev_get_try_crop(&imx500->sd, sd_state, pad); ++ case V4L2_SUBDEV_FORMAT_ACTIVE: ++ return &imx500->mode->crop; ++ } ++ ++ return NULL; ++} ++ ++static int imx500_get_selection(struct v4l2_subdev *sd, ++ struct v4l2_subdev_state *sd_state, ++ struct v4l2_subdev_selection *sel) ++{ ++ switch (sel->target) { ++ case V4L2_SEL_TGT_CROP: { ++ struct imx500 *imx500 = to_imx500(sd); ++ ++ mutex_lock(&imx500->mutex); ++ sel->r = *__imx500_get_pad_crop(imx500, sd_state, sel->pad, ++ sel->which); ++ mutex_unlock(&imx500->mutex); ++ ++ return 0; ++ } ++ ++ case V4L2_SEL_TGT_NATIVE_SIZE: ++ sel->r.left = 0; ++ sel->r.top = 0; ++ sel->r.width = IMX500_NATIVE_WIDTH; ++ sel->r.height = IMX500_NATIVE_HEIGHT; ++ ++ return 0; ++ ++ case V4L2_SEL_TGT_CROP_DEFAULT: ++ case V4L2_SEL_TGT_CROP_BOUNDS: ++ sel->r.left = IMX500_PIXEL_ARRAY_LEFT; ++ sel->r.top = IMX500_PIXEL_ARRAY_TOP; ++ sel->r.width = IMX500_PIXEL_ARRAY_WIDTH; ++ sel->r.height = IMX500_PIXEL_ARRAY_HEIGHT; ++ ++ return 0; ++ } ++ ++ return -EINVAL; ++} ++ ++/* Start streaming */ ++static int imx500_start_streaming(struct imx500 *imx500) ++{ ++ struct i2c_client *client = v4l2_get_subdevdata(&imx500->sd); ++ const struct imx500_reg_list *reg_list; ++ int ret; ++ ++ ret = pm_runtime_resume_and_get(&client->dev); ++ if (ret < 0) ++ return ret; ++ ++ ret = cci_write(imx500->regmap, IMX500_REG_IMAGE_ONLY_MODE, ++ IMX500_IMAGE_ONLY_TRUE, ++ NULL); ++ if (ret) { ++ dev_err(&client->dev, "%s failed to set image mode\n", ++ __func__); ++ return ret; ++ } ++ ++ if (!imx500->common_regs_written) { ++ ret = cci_multi_reg_write(imx500->regmap, mode_common_regs, ++ ARRAY_SIZE(mode_common_regs), NULL); ++ ++ if (ret) { ++ dev_err(&client->dev, ++ "%s failed to set common settings\n", __func__); ++ return ret; ++ } ++ ++ imx500->common_regs_written = true; ++ } ++ ++ /* Apply default values of current mode */ ++ reg_list = &imx500->mode->reg_list; ++ ret = cci_multi_reg_write(imx500->regmap, reg_list->regs, ++ reg_list->num_of_regs, NULL); ++ if (ret) { ++ dev_err(&client->dev, "%s failed to set mode\n", __func__); ++ return ret; ++ } ++ ++ /* Apply customized values from user */ ++ ret = __v4l2_ctrl_handler_setup(imx500->sd.ctrl_handler); ++ ++ /* Disable any sensor startup frame drops. This must be written here! */ ++ cci_write(imx500->regmap, CCI_REG8(0xD405), 0, &ret); ++ ++ /* set stream on register */ ++ cci_write(imx500->regmap, IMX500_REG_MODE_SELECT, IMX500_MODE_STREAMING, ++ &ret); ++ ++ return ret; ++} ++ ++/* Stop streaming */ ++static void imx500_stop_streaming(struct imx500 *imx500) ++{ ++ struct i2c_client *client = v4l2_get_subdevdata(&imx500->sd); ++ int ret; ++ ++ /* set stream off register */ ++ ret = cci_write(imx500->regmap, IMX500_REG_MODE_SELECT, ++ IMX500_MODE_STANDBY, NULL); ++ if (ret) ++ dev_err(&client->dev, "%s failed to set stream\n", __func__); ++ ++ pm_runtime_mark_last_busy(&client->dev); ++ pm_runtime_put_autosuspend(&client->dev); ++} ++ ++static int imx500_set_stream(struct v4l2_subdev *sd, int enable) ++{ ++ struct imx500 *imx500 = to_imx500(sd); ++ int ret = 0; ++ ++ mutex_lock(&imx500->mutex); ++ if (imx500->streaming == enable) { ++ mutex_unlock(&imx500->mutex); ++ return 0; ++ } ++ ++ if (enable) { ++ /* ++ * Apply default & customized values ++ * and then start streaming. ++ */ ++ ret = imx500_start_streaming(imx500); ++ if (ret) ++ goto err_start_streaming; ++ } else { ++ imx500_stop_streaming(imx500); ++ } ++ ++ imx500->streaming = enable; ++ ++ /* vflip and hflip cannot change during streaming */ ++ __v4l2_ctrl_grab(imx500->vflip, enable); ++ __v4l2_ctrl_grab(imx500->hflip, enable); ++ ++ mutex_unlock(&imx500->mutex); ++ ++ return ret; ++ ++err_start_streaming: ++ mutex_unlock(&imx500->mutex); ++ ++ return ret; ++} ++ ++/* Power/clock management functions */ ++static int imx500_power_on(struct device *dev) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct v4l2_subdev *sd = i2c_get_clientdata(client); ++ struct imx500 *imx500 = to_imx500(sd); ++ int ret; ++ ++ ret = regulator_bulk_enable(IMX500_NUM_SUPPLIES, imx500->supplies); ++ if (ret) { ++ dev_err(&client->dev, "%s: failed to enable regulators\n", ++ __func__); ++ return ret; ++ } ++ ++ /* T4 - 1us ++ * Ambiguous: Regulators rising to INCK start is specified by the datasheet ++ * but also "Presence of INCK during Power off is acceptable" ++ */ ++ udelay(2); ++ ++ ret = clk_prepare_enable(imx500->xclk); ++ if (ret) { ++ dev_err(&client->dev, "%s: failed to enable clock\n", __func__); ++ goto reg_off; ++ } ++ ++ /* T5 - 0ms ++ * Ambiguous: Regulators rising to XCLR rising is specified by the datasheet ++ * as 0ms but also "XCLR pin should be set to 'High' after INCK supplied.". ++ * T4 and T5 are shown as overlapping. ++ */ ++ gpiod_set_value_cansleep(imx500->reset_gpio, 1); ++ ++ /* T7 - 9ms ++ * "INCK start and CXLR rising till Send Streaming Command wait time" ++ */ ++ usleep_range(9000, 12000); ++ ++ return 0; ++ ++reg_off: ++ regulator_bulk_disable(IMX500_NUM_SUPPLIES, imx500->supplies); ++ return ret; ++} ++ ++static int imx500_power_off(struct device *dev) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct v4l2_subdev *sd = i2c_get_clientdata(client); ++ struct imx500 *imx500 = to_imx500(sd); ++ ++ /* Datasheet specifies power down sequence as INCK disable, XCLR low, ++ * regulator disable. T1 (XCLR neg-edge to regulator disable) is specified ++ * as 0us. ++ * ++ * Note, this is not the reverse order of power up. ++ */ ++ clk_disable_unprepare(imx500->xclk); ++ gpiod_set_value_cansleep(imx500->reset_gpio, 0); ++ regulator_bulk_disable(IMX500_NUM_SUPPLIES, imx500->supplies); ++ ++ /* Force reprogramming of the common registers when powered up again. */ ++ imx500->common_regs_written = false; ++ ++ return 0; ++} ++ ++static int imx500_get_regulators(struct imx500 *imx500) ++{ ++ struct i2c_client *client = v4l2_get_subdevdata(&imx500->sd); ++ unsigned int i; ++ ++ for (i = 0; i < IMX500_NUM_SUPPLIES; i++) ++ imx500->supplies[i].supply = imx500_supply_name[i]; ++ ++ return devm_regulator_bulk_get(&client->dev, IMX500_NUM_SUPPLIES, ++ imx500->supplies); ++} ++ ++/* Verify chip ID */ ++static int imx500_identify_module(struct imx500 *imx500) ++{ ++ struct i2c_client *client = v4l2_get_subdevdata(&imx500->sd); ++ int ret; ++ u64 val; ++ ++ ret = cci_read(imx500->regmap, IMX500_REG_CHIP_ID, &val, NULL); ++ if (ret) { ++ dev_err(&client->dev, ++ "failed to read chip id %x, with error %d\n", ++ IMX500_CHIP_ID, ret); ++ return ret; ++ } ++ ++ if (val != IMX500_CHIP_ID) { ++ dev_err(&client->dev, "chip id mismatch: %x!=%llx\n", ++ IMX500_CHIP_ID, val); ++ return -EIO; ++ } ++ ++ dev_info(&client->dev, "Device found is imx%llx\n", val); ++ ++ return 0; ++} ++ ++static const struct v4l2_subdev_core_ops imx500_core_ops = { ++ .subscribe_event = v4l2_ctrl_subdev_subscribe_event, ++ .unsubscribe_event = v4l2_event_subdev_unsubscribe, ++}; ++ ++static const struct v4l2_subdev_video_ops imx500_video_ops = { ++ .s_stream = imx500_set_stream, ++}; ++ ++static const struct v4l2_subdev_pad_ops imx500_pad_ops = { ++ .enum_mbus_code = imx500_enum_mbus_code, ++ .get_fmt = imx500_get_pad_format, ++ .set_fmt = imx500_set_pad_format, ++ .get_selection = imx500_get_selection, ++ .enum_frame_size = imx500_enum_frame_size, ++}; ++ ++static const struct v4l2_subdev_ops imx500_subdev_ops = { ++ .core = &imx500_core_ops, ++ .video = &imx500_video_ops, ++ .pad = &imx500_pad_ops, ++}; ++ ++static const s64 imx500_link_freq_menu[] = { ++ IMX500_DEFAULT_LINK_FREQ, ++}; ++ ++/* Initialize control handlers */ ++static int imx500_init_controls(struct imx500 *imx500) ++{ ++ struct v4l2_ctrl_handler *ctrl_hdlr; ++ struct i2c_client *client = v4l2_get_subdevdata(&imx500->sd); ++ struct v4l2_fwnode_device_properties props; ++ int ret; ++ ++ ctrl_hdlr = &imx500->ctrl_handler; ++ ret = v4l2_ctrl_handler_init(ctrl_hdlr, 16); ++ if (ret) ++ return ret; ++ ++ mutex_init(&imx500->mutex); ++ ctrl_hdlr->lock = &imx500->mutex; ++ ++ /* By default, PIXEL_RATE is read only */ ++ imx500->pixel_rate = v4l2_ctrl_new_std( ++ ctrl_hdlr, &imx500_ctrl_ops, V4L2_CID_PIXEL_RATE, ++ IMX500_PIXEL_RATE, IMX500_PIXEL_RATE, 1, IMX500_PIXEL_RATE); ++ ++ /* LINK_FREQ is also read only */ ++ imx500->link_freq = ++ v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx500_ctrl_ops, ++ V4L2_CID_LINK_FREQ, ++ ARRAY_SIZE(imx500_link_freq_menu) - 1, 0, ++ imx500_link_freq_menu); ++ if (imx500->link_freq) ++ imx500->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; ++ ++ /* ++ * Create the controls here, but mode specific limits are setup ++ * in the imx500_set_framing_limits() call below. ++ */ ++ imx500->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx500_ctrl_ops, ++ V4L2_CID_VBLANK, 0, 0xffff, 1, 0); ++ imx500->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx500_ctrl_ops, ++ V4L2_CID_HBLANK, 0, 0xffff, 1, 0); ++ ++ imx500->exposure = v4l2_ctrl_new_std( ++ ctrl_hdlr, &imx500_ctrl_ops, V4L2_CID_EXPOSURE, ++ IMX500_EXPOSURE_MIN, IMX500_EXPOSURE_MAX, IMX500_EXPOSURE_STEP, ++ IMX500_EXPOSURE_DEFAULT); ++ ++ v4l2_ctrl_new_std(ctrl_hdlr, &imx500_ctrl_ops, V4L2_CID_ANALOGUE_GAIN, ++ IMX500_ANA_GAIN_MIN, IMX500_ANA_GAIN_MAX, ++ IMX500_ANA_GAIN_STEP, IMX500_ANA_GAIN_DEFAULT); ++ ++ imx500->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx500_ctrl_ops, ++ V4L2_CID_HFLIP, 0, 1, 1, 0); ++ if (imx500->hflip) ++ imx500->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; ++ ++ imx500->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx500_ctrl_ops, ++ V4L2_CID_VFLIP, 0, 1, 1, 0); ++ if (imx500->vflip) ++ imx500->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; ++ ++ v4l2_ctrl_new_custom(ctrl_hdlr, &imx500_notify_gains_ctrl, NULL); ++ ++ if (ctrl_hdlr->error) { ++ ret = ctrl_hdlr->error; ++ dev_err(&client->dev, "%s control init failed (%d)\n", __func__, ++ ret); ++ goto error; ++ } ++ ++ ret = v4l2_fwnode_device_parse(&client->dev, &props); ++ if (ret) ++ goto error; ++ ++ ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &imx500_ctrl_ops, ++ &props); ++ if (ret) ++ goto error; ++ ++ imx500->sd.ctrl_handler = ctrl_hdlr; ++ ++ /* Setup exposure and frame/line length limits. */ ++ imx500_set_framing_limits(imx500); ++ ++ return 0; ++ ++error: ++ v4l2_ctrl_handler_free(ctrl_hdlr); ++ mutex_destroy(&imx500->mutex); ++ ++ return ret; ++} ++ ++static void imx500_free_controls(struct imx500 *imx500) ++{ ++ v4l2_ctrl_handler_free(imx500->sd.ctrl_handler); ++ mutex_destroy(&imx500->mutex); ++} ++ ++static int imx500_check_hwcfg(struct device *dev) ++{ ++ struct fwnode_handle *endpoint; ++ struct v4l2_fwnode_endpoint ep_cfg = { .bus_type = ++ V4L2_MBUS_CSI2_DPHY }; ++ int ret = -EINVAL; ++ ++ endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL); ++ if (!endpoint) { ++ dev_err(dev, "endpoint node not found\n"); ++ return -EINVAL; ++ } ++ ++ if (v4l2_fwnode_endpoint_alloc_parse(endpoint, &ep_cfg)) { ++ dev_err(dev, "could not parse endpoint\n"); ++ goto error_out; ++ } ++ ++ /* Check the number of MIPI CSI2 data lanes */ ++ if (ep_cfg.bus.mipi_csi2.num_data_lanes != 2) { ++ dev_err(dev, "only 2 data lanes are currently supported\n"); ++ goto error_out; ++ } ++ ++ /* Check the link frequency set in device tree */ ++ if (!ep_cfg.nr_of_link_frequencies) { ++ dev_err(dev, "link-frequency property not found in DT\n"); ++ goto error_out; ++ } ++ ++ if (ep_cfg.nr_of_link_frequencies != 1 || ++ ep_cfg.link_frequencies[0] != IMX500_DEFAULT_LINK_FREQ) { ++ dev_err(dev, "Link frequency not supported: %lld\n", ++ ep_cfg.link_frequencies[0]); ++ goto error_out; ++ } ++ ++ ret = 0; ++ ++error_out: ++ v4l2_fwnode_endpoint_free(&ep_cfg); ++ fwnode_handle_put(endpoint); ++ ++ return ret; ++} ++ ++static int imx500_probe(struct i2c_client *client) ++{ ++ struct device *dev = &client->dev; ++ struct imx500 *imx500; ++ int ret; ++ ++ imx500 = devm_kzalloc(&client->dev, sizeof(*imx500), GFP_KERNEL); ++ if (!imx500) ++ return -ENOMEM; ++ ++ imx500->regmap = devm_cci_regmap_init_i2c(client, 16); ++ if (IS_ERR(imx500->regmap)) ++ return dev_err_probe(dev, PTR_ERR(imx500->regmap), ++ "failed to initialise CCI\n"); ++ ++ v4l2_i2c_subdev_init(&imx500->sd, client, &imx500_subdev_ops); ++ ++ /* Check the hardware configuration in device tree */ ++ if (imx500_check_hwcfg(dev)) ++ return -EINVAL; ++ ++ /* Get system clock (xclk) */ ++ imx500->xclk = devm_clk_get(dev, NULL); ++ if (IS_ERR(imx500->xclk)) ++ return dev_err_probe(dev, PTR_ERR(imx500->xclk), ++ "failed to get xclk\n"); ++ ++ imx500->xclk_freq = clk_get_rate(imx500->xclk); ++ if (imx500->xclk_freq != IMX500_XCLK_FREQ) { ++ dev_err(dev, "xclk frequency not supported: %d Hz\n", ++ imx500->xclk_freq); ++ return -EINVAL; ++ } ++ ++ ret = imx500_get_regulators(imx500); ++ if (ret) { ++ dev_err(dev, "failed to get regulators\n"); ++ return ret; ++ } ++ ++ imx500->reset_gpio = ++ devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); ++ ++ /* ++ * The sensor must be powered for imx500_identify_module() ++ * to be able to read the CHIP_ID register ++ */ ++ ret = imx500_power_on(dev); ++ if (ret) ++ return ret; ++ ++ pm_runtime_set_active(dev); ++ pm_runtime_get_noresume(dev); ++ pm_runtime_enable(dev); ++ pm_runtime_set_autosuspend_delay(dev, 5000); ++ pm_runtime_use_autosuspend(dev); ++ ++ ret = imx500_identify_module(imx500); ++ if (ret) ++ goto error_power_off; ++ ++ /* Initialize default format */ ++ imx500_set_default_format(imx500); ++ ++ /* This needs the pm runtime to be registered. */ ++ ret = imx500_init_controls(imx500); ++ if (ret) ++ goto error_power_off; ++ ++ /* Initialize subdev */ ++ imx500->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | ++ V4L2_SUBDEV_FL_HAS_EVENTS; ++ imx500->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; ++ ++ /* Initialize source pads */ ++ imx500->pad.flags = MEDIA_PAD_FL_SOURCE; ++ ++ ret = media_entity_pads_init(&imx500->sd.entity, NUM_PADS, ++ &imx500->pad); ++ if (ret) { ++ dev_err(dev, "failed to init entity pads: %d\n", ret); ++ goto error_handler_free; ++ } ++ ++ ret = v4l2_async_register_subdev_sensor(&imx500->sd); ++ if (ret < 0) { ++ dev_err(dev, "failed to register sensor sub-device: %d\n", ret); ++ goto error_media_entity; ++ } ++ ++ pm_runtime_mark_last_busy(&client->dev); ++ pm_runtime_put_autosuspend(&client->dev); ++ ++ return 0; ++ ++error_media_entity: ++ media_entity_cleanup(&imx500->sd.entity); ++ ++error_handler_free: ++ imx500_free_controls(imx500); ++ ++error_power_off: ++ pm_runtime_disable(&client->dev); ++ pm_runtime_put_noidle(&client->dev); ++ imx500_power_off(&client->dev); ++ ++ return ret; ++} ++ ++static void imx500_remove(struct i2c_client *client) ++{ ++ struct v4l2_subdev *sd = i2c_get_clientdata(client); ++ struct imx500 *imx500 = to_imx500(sd); ++ ++ v4l2_async_unregister_subdev(sd); ++ media_entity_cleanup(&sd->entity); ++ imx500_free_controls(imx500); ++ ++ pm_runtime_disable(&client->dev); ++ if (!pm_runtime_status_suspended(&client->dev)) ++ imx500_power_off(&client->dev); ++ pm_runtime_set_suspended(&client->dev); ++} ++ ++static const struct of_device_id imx500_dt_ids[] = { ++ { .compatible = "sony,imx500" }, ++ { /* sentinel */ } ++}; ++ ++MODULE_DEVICE_TABLE(of, imx500_dt_ids); ++ ++static const struct dev_pm_ops imx500_pm_ops = { SET_RUNTIME_PM_OPS( ++ imx500_power_off, imx500_power_on, NULL) }; ++ ++static struct i2c_driver imx500_i2c_driver = { ++ .driver = { ++ .name = "imx500", ++ .of_match_table = imx500_dt_ids, ++ .pm = &imx500_pm_ops, ++ }, ++ .probe = imx500_probe, ++ .remove = imx500_remove, ++}; ++ ++module_i2c_driver(imx500_i2c_driver); ++ ++MODULE_AUTHOR("Naushir Patuck "); ++MODULE_DESCRIPTION("Sony IMX500 sensor driver"); ++MODULE_LICENSE("GPL"); diff --git a/target/linux/bcm27xx/patches-6.6/950-1245-lib-earlycpio-export-symbol-find_cpio_data.patch b/target/linux/bcm27xx/patches-6.6/950-1245-lib-earlycpio-export-symbol-find_cpio_data.patch new file mode 100644 index 00000000000..f749e848484 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1245-lib-earlycpio-export-symbol-find_cpio_data.patch @@ -0,0 +1,20 @@ +From a32f7dae82774d6064181dcc989c1c1349c4e47e Mon Sep 17 00:00:00 2001 +From: Richard Oliver +Date: Thu, 20 Jun 2024 09:58:32 +0100 +Subject: [PATCH 1245/1350] lib: earlycpio: export symbol find_cpio_data() + +Add EXPORT_SYMBOL_GPL() for find_cpio_data() so that loadable modules +may also parse uncompressed cpio. + +Signed-off-by: Richard Oliver +--- + lib/earlycpio.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/lib/earlycpio.c ++++ b/lib/earlycpio.c +@@ -139,3 +139,4 @@ struct cpio_data find_cpio_data(const ch + quit: + return cd; + } ++EXPORT_SYMBOL_GPL(find_cpio_data); diff --git a/target/linux/bcm27xx/patches-6.6/950-1246-media-i2c-imx500-Inbuilt-AI-processor-support.patch b/target/linux/bcm27xx/patches-6.6/950-1246-media-i2c-imx500-Inbuilt-AI-processor-support.patch new file mode 100644 index 00000000000..9a0642b375e --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1246-media-i2c-imx500-Inbuilt-AI-processor-support.patch @@ -0,0 +1,1631 @@ +From 97f4ec49828877642e4a87f9c2f47c7a9dd10b90 Mon Sep 17 00:00:00 2001 +From: Richard Oliver +Date: Wed, 24 Jul 2024 13:06:16 +0100 +Subject: [PATCH 1246/1350] media: i2c: imx500: Inbuilt AI processor support + +Add support for the IMX500's inbuilt AI processor. The IMX500 program +loader, AI processor firmware, DNN weights are accessed via the kernel's +firmware interface on 'open' and are transferred to the IMX500 over SPI. + +Signed-off-by: Richard Oliver +--- + drivers/media/i2c/imx500.c | 1322 +++++++++++++++++++++++++++- + include/uapi/linux/v4l2-controls.h | 6 + + 2 files changed, 1290 insertions(+), 38 deletions(-) + +--- a/drivers/media/i2c/imx500.c ++++ b/drivers/media/i2c/imx500.c +@@ -5,9 +5,14 @@ + */ + #include + #include ++#include + #include ++#include ++#include + #include + #include ++#include ++#include + #include + #include + #include +@@ -67,6 +72,138 @@ + #define IMX500_ANA_GAIN_STEP 1 + #define IMX500_ANA_GAIN_DEFAULT 0x0 + ++/* Inference windows */ ++#define IMX500_REG_DWP_AP_VC_VOFF CCI_REG16(0xD500) ++#define IMX500_REG_DWP_AP_VC_HOFF CCI_REG16(0xD502) ++#define IMX500_REG_DWP_AP_VC_VSIZE CCI_REG16(0xD504) ++#define IMX500_REG_DWP_AP_VC_HSIZE CCI_REG16(0xD506) ++ ++#define IMX500_REG_DD_CH06_X_OUT_SIZE \ ++ CCI_REG16(0x3054) /* Output pixel count for KPI */ ++#define IMX500_REG_DD_CH07_X_OUT_SIZE \ ++ CCI_REG16(0x3056) /* Output pixel count for Input Tensor */ ++#define IMX500_REG_DD_CH08_X_OUT_SIZE \ ++ CCI_REG16(0x3058) /* Output pixel count for Output Tensor */ ++#define IMX500_REG_DD_CH09_X_OUT_SIZE \ ++ CCI_REG16(0x305A) /* Output pixel count for PQ Settings */ ++ ++#define IMX500_REG_DD_CH06_Y_OUT_SIZE \ ++ CCI_REG16(0x305C) /* Output line count for KPI */ ++#define IMX500_REG_DD_CH07_Y_OUT_SIZE \ ++ CCI_REG16(0x305E) /* Output line count for Input Tensor */ ++#define IMX500_REG_DD_CH08_Y_OUT_SIZE \ ++ CCI_REG16(0x3060) /* Output line count for Output Tensor */ ++#define IMX500_REG_DD_CH09_Y_OUT_SIZE \ ++ CCI_REG16(0x3062) /* Output line count for PQ Settings */ ++ ++#define IMX500_REG_DD_CH06_VCID \ ++ CCI_REG8(0x3064) /* Virtual channel ID for KPI */ ++#define IMX500_REG_DD_CH07_VCID \ ++ CCI_REG8(0x3065) /* Virtual channel ID for Input Tensor */ ++#define IMX500_REG_DD_CH08_VCID \ ++ CCI_REG8(0x3066) /* Virtual channel ID for Output Tensor */ ++#define IMX500_REG_DD_CH09_VCID \ ++ CCI_REG8(0x3067) /* Virtual channel ID for PQ Settings */ ++ ++#define IMX500_REG_DD_CH06_DT CCI_REG8(0x3068) /* Data Type for KPI */ ++#define IMX500_REG_DD_CH07_DT CCI_REG8(0x3069) /* Data Type for Input Tensor */ ++#define IMX500_REG_DD_CH08_DT CCI_REG8(0x306A) /* Data Type for Output Tensor */ ++#define IMX500_REG_DD_CH09_DT CCI_REG8(0x306B) /* Data Type for PQ Settings */ ++ ++#define IMX500_REG_DD_CH06_PACKING \ ++ CCI_REG8(0x306C) /* Pixel/byte packing for KPI */ ++#define IMX500_REG_DD_CH07_PACKING \ ++ CCI_REG8(0x306D) /* Pixel/byte packing for Input Tensor */ ++#define IMX500_REG_DD_CH08_PACKING \ ++ CCI_REG8(0x306E) /* Pixel/byte packing for Output Tensor */ ++#define IMX500_REG_DD_CH09_PACKING \ ++ CCI_REG8(0x306F) /* Pixel/byte packing for PQ Settings */ ++#define IMX500_DD_PACKING_8BPP 2 /* 8 bits/pixel */ ++#define IMX500_DD_PACKING_10BPP 3 /* 10 bits/pixel */ ++ ++/* Interrupt command (start processing command inside IMX500 CPU) */ ++#define IMX500_REG_DD_CMD_INT CCI_REG8(0x3080) ++#define IMX500_DD_CMD_INT_ST_TRANS 0 ++#define IMX500_DD_CMD_INT_UPDATE 1 ++#define IMX500_DD_CMD_INT_FLASH_ERASE 2 ++ ++/* State transition command type */ ++#define IMX500_REG_DD_ST_TRANS_CMD CCI_REG8(0xD000) ++#define IMX500_DD_ST_TRANS_CMD_LOADER_FW 0 ++#define IMX500_DD_ST_TRANS_CMD_MAIN_FW 1 ++#define IMX500_DD_ST_TRANS_CMD_NW_WEIGHTS 2 ++#define IMX500_DD_ST_TRANS_CMD_CLEAR_WEIGHTS 3 ++ ++/* Network weights update command */ ++#define IMX500_REG_DD_UPDATE_CMD CCI_REG8(0xD001) ++#define IMX500_DD_UPDATE_CMD_SRAM 0 ++#define IMX500_DD_UPDATE_CMD_FLASH 1 ++ ++/* Transfer source when loading into RAM */ ++#define IMX500_REG_DD_LOAD_MODE CCI_REG8(0xD002) ++#define IMX500_DD_LOAD_MODE_AP 0 ++#define IMX500_DD_LOAD_MODE_FLASH 1 ++ ++/* Image type to transfer */ ++#define IMX500_REG_DD_IMAGE_TYPE CCI_REG8(0xD003) ++#define IMX500_DD_IMAGE_TYPE_LOADER_FW 0 ++#define IMX500_DD_IMAGE_TYPE_MAIN_FW 1 ++#define IMX500_DD_IMAGE_TYPE_NETWORK_WEIGHTS 2 ++ ++/* Number of divisions of download image file */ ++#define IMX500_REG_DD_DOWNLOAD_DIV_NUM CCI_REG8(0xD004) ++ ++#define IMX500_REG_DD_FLASH_TYPE CCI_REG8(0xD005) ++ ++/* total size of download file (4-byte) */ ++#define IMX500_REG_DD_DOWNLOAD_FILE_SIZE CCI_REG32(0xD008) ++ ++/* Status notification (4-byte) */ ++#define IMX500_REG_DD_REF_STS CCI_REG32(0xD010) ++#define IMX500_DD_REF_STS_FATAL 0xFF ++#define IMX500_DD_REF_STS_DETECT_CNT 0xFF00 ++#define IMX500_DD_REF_STS_ERR_CNT 0xFF0000 ++#define IMX500_DD_REF_CMD_REPLY_CNT 0xFF000000 ++ ++/* Command reply status */ ++#define IMX500_REG_DD_CMD_REPLY_STS CCI_REG8(0xD014) ++#define IMX500_DD_CMD_REPLY_STS_TRANS_READY 0x00 ++#define IMX500_DD_CMD_REPLY_STS_TRANS_DONE 0x01 ++#define IMX500_DD_CMD_REPLY_STS_UPDATE_READY 0x10 ++#define IMX500_DD_CMD_REPLY_STS_UPDATE_DONE 0x11 ++#define IMX500_DD_CMD_REPLY_STS_UPDATE_CANCEL_DONE 0x12 ++#define IMX500_DD_CMD_REPLY_STS_STATUS_ERROR 0xFF ++#define IMX500_DD_CMD_REPLY_STS_MAC_AUTH_ERROR 0xFE ++#define IMX500_DD_CMD_REPLY_STS_TIMEOUT_ERROR 0xFD ++#define IMX500_DD_CMD_REPLY_STS_PARAMETER_ERROR 0xFC ++#define IMX500_DD_CMD_REPLY_STS_INTERNAL_ERROR 0xFB ++#define IMX500_DD_CMD_REPLY_STS_PACKET_FMT_ERROR 0xFA ++ ++/* Download status */ ++#define IMX500_REG_DD_DOWNLOAD_STS CCI_REG8(0xD015) ++#define IMX500_DD_DOWNLOAD_STS_READY 0 ++#define IMX500_DD_DOWNLOAD_STS_DOWNLOADING 1 ++ ++/* Update cancel */ ++#define IMX500_REG_DD_UPDATE_CANCEL CCI_REG8(0xD016) ++#define IMX500_DD_UPDATE_CANCEL_NOT_CANCEL 0 ++#define IMX500_DD_UPDATE_CANCEL_DO_CANCEL 1 ++ ++/* Notify error status */ ++#define IMX500_REG_DD_ERR_STS CCI_REG8(0xD020) ++#define IMX500_DD_ERR_STS_STATUS_ERROR_BIT 0x1 ++#define IMX500_DD_ERR_STS_INTERNAL_ERROR_BIT 0x2 ++#define IMX500_DD_ERR_STS_PARAMETER_ERROR_BIT 0x4 ++ ++/* System state */ ++#define IMX500_REG_DD_SYS_STATE CCI_REG8(0xD02A) ++#define IMX500_DD_SYS_STATE_STANDBY_NO_NETWORK 0 ++#define IMX500_DD_SYS_STATE_STEAMING_NO_NETWORK 1 ++#define IMX500_DD_SYS_STATE_STANDBY_WITH_NETWORK 2 ++#define IMX500_DD_SYS_STATE_STREAMING_WITH_NETWORK 3 ++ ++#define IMX500_REG_MAIN_FW_VERSION CCI_REG32(0xD07C) ++ + /* Colour balance controls */ + #define IMX500_REG_COLOUR_BALANCE_R CCI_REG16(0xd804) + #define IMX500_REG_COLOUR_BALANCE_GR CCI_REG16(0xd806) +@@ -81,6 +218,11 @@ + #define IMX500_MAX_EMBEDDED_SIZE \ + (2 * ((((IMX500_PIXEL_ARRAY_WIDTH * 10) >> 3) + 15) & ~15)) + ++/* Inference sizes */ ++#define IMX500_INFERENCE_LINE_WIDTH 2560 ++#define IMX500_NUM_KPI_LINES 1 ++#define IMX500_NUM_PQ_LINES 1 ++ + /* IMX500 native and active pixel array size. */ + #define IMX500_NATIVE_WIDTH 4072U + #define IMX500_NATIVE_HEIGHT 3176U +@@ -89,7 +231,12 @@ + #define IMX500_PIXEL_ARRAY_WIDTH 4056U + #define IMX500_PIXEL_ARRAY_HEIGHT 3040U + +-#define NUM_PADS 1 ++enum pad_types { IMAGE_PAD, METADATA_PAD, NUM_PADS }; ++ ++#define V4L2_CID_USER_IMX500_INFERENCE_WINDOW (V4L2_CID_USER_IMX500_BASE + 0) ++#define V4L2_CID_USER_IMX500_NETWORK_FW_FD (V4L2_CID_USER_IMX500_BASE + 1) ++ ++#define ONE_MIB (1024 * 1024) + + /* regulator supplies */ + static const char *const imx500_supply_name[] = { +@@ -101,6 +248,13 @@ static const char *const imx500_supply_n + + #define IMX500_NUM_SUPPLIES ARRAY_SIZE(imx500_supply_name) + ++enum imx500_image_type { ++ TYPE_LOADER = 0, ++ TYPE_MAIN = 1, ++ TYPE_NW_WEIGHTS = 2, ++ TYPE_MAX ++}; ++ + struct imx500_reg_list { + unsigned int num_of_regs; + const struct cci_reg_sequence *regs; +@@ -135,10 +289,19 @@ static const struct cci_reg_sequence mod + { CCI_REG8(0x0106), 0x01 }, /* FAST_STANDBY_CTL */ + { CCI_REG8(0x0136), 0x1b }, /* EXCLK_FREQ */ + { CCI_REG8(0x0137), 0x00 }, +- { CCI_REG8(0x0138), 0x01 }, /* TEMP_SENS_CTL */ + { CCI_REG8(0x0112), 0x0a }, + { CCI_REG8(0x0113), 0x0a }, + { CCI_REG8(0x0114), 0x01 }, /* CSI_LANE_MODE */ ++ { CCI_REG16(0x3054), IMX500_INFERENCE_LINE_WIDTH }, ++ { CCI_REG16(0x3056), IMX500_INFERENCE_LINE_WIDTH }, ++ { CCI_REG16(0x3058), IMX500_INFERENCE_LINE_WIDTH }, ++ { CCI_REG16(0x305A), IMX500_INFERENCE_LINE_WIDTH }, /* X_OUT */ ++ { CCI_REG16(0x305C), IMX500_NUM_KPI_LINES }, /* KPI Y_OUT */ ++ { CCI_REG16(0x3062), IMX500_NUM_PQ_LINES }, /* PQ Y_OUT */ ++ { CCI_REG8(0x3068), 0x30 }, ++ { CCI_REG8(0x3069), 0x31 }, ++ { CCI_REG8(0x306A), 0x32 }, ++ { CCI_REG8(0x306B), 0x33 }, /* Data Types */ + }; + + /* 12 mpix 15fps */ +@@ -624,6 +787,111 @@ static const struct cci_reg_sequence mod + { CCI_REG8(0x0215), 0x00 }, + }; + ++static const struct cci_reg_sequence metadata_output[] = { ++ { CCI_REG8(0x3050), 1 }, /* MIPI Output enabled */ ++ { CCI_REG8(0x3051), 1 }, /* MIPI output frame includes pixels data */ ++ { CCI_REG8(0x3052), 1 }, /* MIPI output frame includes meta data */ ++ { IMX500_REG_DD_CH06_VCID, 0 }, ++ { IMX500_REG_DD_CH07_VCID, 0 }, ++ { IMX500_REG_DD_CH08_VCID, 0 }, ++ { IMX500_REG_DD_CH09_VCID, 0 }, ++ { IMX500_REG_DD_CH06_DT, ++ 0x12 }, /* KPI - User Defined 8-bit Data Type 1 */ ++ { IMX500_REG_DD_CH07_DT, 0x12 }, /* Input Tensor - U.D. 8-bit type 2 */ ++ { IMX500_REG_DD_CH08_DT, 0x12 }, /* Output Tensor - U.D. 8-bit type 3 */ ++ { IMX500_REG_DD_CH09_DT, 0x12 }, /* PQ - U.D. 8-bit type 4 */ ++ { IMX500_REG_DD_CH06_PACKING, IMX500_DD_PACKING_8BPP }, ++ { IMX500_REG_DD_CH07_PACKING, IMX500_DD_PACKING_8BPP }, ++ { IMX500_REG_DD_CH08_PACKING, IMX500_DD_PACKING_8BPP }, ++ { IMX500_REG_DD_CH09_PACKING, IMX500_DD_PACKING_8BPP }, ++}; ++ ++static const struct cci_reg_sequence dnn_regs[] = { ++ { CCI_REG8(0xd960), 0x52 }, ++ { CCI_REG8(0xd961), 0x52 }, ++ { CCI_REG8(0xd962), 0x52 }, ++ { CCI_REG8(0xd963), 0x52 }, ++ { CCI_REG8(0xd96c), 0x44 }, ++ { CCI_REG8(0xd96d), 0x44 }, ++ { CCI_REG8(0xd96e), 0x44 }, ++ { CCI_REG8(0xd96f), 0x44 }, ++ { CCI_REG8(0xd600), 0x20 }, ++ /* Black level */ ++ { CCI_REG16(0xd80c), 0x100 }, ++ { CCI_REG16(0xd80e), 0x100 }, ++ { CCI_REG16(0xd810), 0x100 }, ++ { CCI_REG16(0xd812), 0x100 }, ++ /* Gamma */ ++ { CCI_REG8(0xd814), 1 }, ++ { CCI_REG32(0xd850), 0x10000 }, ++ { CCI_REG32(0xd854), 0x40002 }, ++ { CCI_REG32(0xd858), 0x60005 }, ++ { CCI_REG32(0xd85c), 0x90008 }, ++ { CCI_REG32(0xd860), 0xc000a }, ++ { CCI_REG32(0xd864), 0x12000f }, ++ { CCI_REG32(0xd868), 0x1c0014 }, ++ { CCI_REG32(0xd86c), 0x2a0024 }, ++ { CCI_REG32(0xd870), 0x360030 }, ++ { CCI_REG32(0xd874), 0x46003c }, ++ { CCI_REG32(0xd878), 0x5a0051 }, ++ { CCI_REG32(0xd87c), 0x750064 }, ++ { CCI_REG32(0xd880), 0x920084 }, ++ { CCI_REG32(0xd884), 0xa9009e }, ++ { CCI_REG32(0xd888), 0xba00b2 }, ++ { CCI_REG32(0xd88c), 0xc700c1 }, ++ { CCI_REG32(0xd890), 0xd100cd }, ++ { CCI_REG32(0xd894), 0xde00d6 }, ++ { CCI_REG32(0xd898), 0xe900e4 }, ++ { CCI_REG32(0xd89c), 0xf300ee }, ++ { CCI_REG32(0xd8a0), 0xfb00f7 }, ++ { CCI_REG16(0xd8a4), 0xff }, ++ { CCI_REG32(0xd8a8), 0x10000 }, ++ { CCI_REG32(0xd8ac), 0x40002 }, ++ { CCI_REG32(0xd8b0), 0x60005 }, ++ { CCI_REG32(0xd8b4), 0x90008 }, ++ { CCI_REG32(0xd8b8), 0xc000a }, ++ { CCI_REG32(0xd8bc), 0x12000f }, ++ { CCI_REG32(0xd8c0), 0x1c0014 }, ++ { CCI_REG32(0xd8c4), 0x2a0024 }, ++ { CCI_REG32(0xd8c8), 0x360030 }, ++ { CCI_REG32(0xd8cc), 0x46003c }, ++ { CCI_REG32(0xd8d0), 0x5a0051 }, ++ { CCI_REG32(0xd8d4), 0x750064 }, ++ { CCI_REG32(0xd8d8), 0x920084 }, ++ { CCI_REG32(0xd8dc), 0xa9009e }, ++ { CCI_REG32(0xd8e0), 0xba00b2 }, ++ { CCI_REG32(0xd8e4), 0xc700c1 }, ++ { CCI_REG32(0xd8e8), 0xd100cd }, ++ { CCI_REG32(0xd8ec), 0xde00d6 }, ++ { CCI_REG32(0xd8f0), 0xe900e4 }, ++ { CCI_REG32(0xd8f4), 0xf300ee }, ++ { CCI_REG32(0xd8f8), 0xfb00f7 }, ++ { CCI_REG16(0xd8fc), 0xff }, ++ { CCI_REG32(0xd900), 0x10000 }, ++ { CCI_REG32(0xd904), 0x40002 }, ++ { CCI_REG32(0xd908), 0x60005 }, ++ { CCI_REG32(0xd90c), 0x90008 }, ++ { CCI_REG32(0xd910), 0xc000a }, ++ { CCI_REG32(0xd914), 0x12000f }, ++ { CCI_REG32(0xd918), 0x1c0014 }, ++ { CCI_REG32(0xd91c), 0x2a0024 }, ++ { CCI_REG32(0xd920), 0x360030 }, ++ { CCI_REG32(0xd924), 0x46003c }, ++ { CCI_REG32(0xd928), 0x5a0051 }, ++ { CCI_REG32(0xd92c), 0x750064 }, ++ { CCI_REG32(0xd930), 0x920084 }, ++ { CCI_REG32(0xd934), 0xa9009e }, ++ { CCI_REG32(0xd938), 0xba00b2 }, ++ { CCI_REG32(0xd93c), 0xc700c1 }, ++ { CCI_REG32(0xd940), 0xd100cd }, ++ { CCI_REG32(0xd944), 0xde00d6 }, ++ { CCI_REG32(0xd948), 0xe900e4 }, ++ { CCI_REG32(0xd94c), 0xf300ee }, ++ { CCI_REG32(0xd950), 0xfb00f7 }, ++ { CCI_REG16(0xd954), 0xff }, ++ { CCI_REG8(0xd826), 1 }, ++}; ++ + /* Mode configs */ + static const struct imx500_mode imx500_supported_modes[] = { + { +@@ -679,9 +947,17 @@ static const u32 codes[] = { + MEDIA_BUS_FMT_SBGGR10_1X10, + }; + ++enum imx500_state { ++ IMX500_STATE_RESET = 0, ++ IMX500_STATE_PROGRAM_EMPTY, ++ IMX500_STATE_WITHOUT_NETWORK, ++ IMX500_STATE_WITH_NETWORK, ++}; ++ + struct imx500 { ++ struct dentry *debugfs; + struct v4l2_subdev sd; +- struct media_pad pad; ++ struct media_pad pad[NUM_PADS]; + struct regmap *regmap; + + unsigned int fmt_code; +@@ -701,6 +977,9 @@ struct imx500 { + struct v4l2_ctrl *hflip; + struct v4l2_ctrl *vblank; + struct v4l2_ctrl *hblank; ++ struct v4l2_ctrl *network_fw_ctrl; ++ ++ struct v4l2_rect inference_window; + + /* Current mode */ + const struct imx500_mode *mode; +@@ -717,8 +996,24 @@ struct imx500 { + /* Rewrite common registers on stream on? */ + bool common_regs_written; + ++ bool loader_and_main_written; ++ bool network_written; ++ + /* Current long exposure factor in use. Set through V4L2_CID_VBLANK */ + unsigned int long_exp_shift; ++ ++ struct spi_device *spi_device; ++ ++ const struct firmware *fw_loader; ++ const struct firmware *fw_main; ++ const u8 *fw_network; ++ size_t fw_network_size; ++ size_t fw_progress; ++ unsigned int fw_stage; ++ ++ enum imx500_state fsm_state; ++ ++ u32 num_inference_lines; + }; + + static inline struct imx500 *to_imx500(struct v4l2_subdev *_sd) +@@ -726,6 +1021,188 @@ static inline struct imx500 *to_imx500(s + return container_of(_sd, struct imx500, sd); + } + ++static bool validate_normalization_yuv(u16 reg, uint8_t size, ++ uint32_t value) ++{ ++ /* Some regs are 9-bit, some 8-bit, some 1-bit */ ++ switch (reg) { ++ case 0xD62A: ++ case 0xD632: ++ case 0xD63A: ++ case 0xD644: ++ case 0xD648: ++ case 0xD64C: ++ case 0xD650: ++ case 0xD654: ++ case 0xD658: ++ return size == 2 && !(value & ~0x1FF); ++ case 0xD600: ++ case 0xD601: ++ case 0xD602: ++ return size == 1 && !(value & ~0xFF); ++ case 0xD629: ++ case 0xD630: ++ case 0xD638: ++ case 0xD643: ++ case 0xD647: ++ case 0xD64B: ++ case 0xD64F: ++ case 0xD653: ++ case 0xD657: ++ return size == 1 && !(value & ~0x01); ++ default: ++ return false; ++ } ++} ++ ++/* Common function as bayer rgb + normalization use the same repeating register ++ * layout ++ */ ++static bool validate_bit_pattern(u8 offset, uint8_t size, uint32_t value) ++{ ++ /* There are no odd register addresses */ ++ if (offset & 1) ++ return false; ++ ++ /* Valid register sizes/patterns repeat every 4 */ ++ offset = (offset >> 1) & 3; ++ ++ if (offset == 1) ++ return size == 1 && !(value & ~1); ++ else ++ return size == 2 && !(value & ~0x1FF); ++} ++ ++static bool validate_bayer_rgb_normalization(u16 reg, uint8_t size, ++ uint32_t value) ++{ ++ if (reg < 0xD684 || reg >= 0xD6E4) ++ return false; ++ return validate_bit_pattern(reg - 0xD684, size, value); ++} ++ ++static bool validate_normalization_registers(u16 reg, uint8_t size, ++ uint32_t value) ++{ ++ if (reg < 0xD708 || reg >= 0xD750) ++ return false; ++ return validate_bit_pattern(reg - 0xD708, size, value); ++} ++ ++static bool validate_image_format_selection(u16 reg, uint8_t size, ++ uint32_t value) ++{ ++ if (size != 1 || value > 5) ++ return false; ++ if (reg < 0xD750 || reg > 0xd752) ++ return false; ++ return true; ++} ++ ++static bool validate_yc_conversion_factor(u16 reg, uint8_t size, ++ uint32_t value) ++{ ++ static const u32 allowed[9] = { ++ 0x0FFF0FFF, 0x0FFF1FFF, 0x0FFF0FFF, 0x0FFF1FFF, 0x0FFF0FFF, ++ 0x0FFF1FFF, 0x01FF01FF, 0x01FF01FF, 0x01FF01FF, ++ }; ++ ++ if (size > 4 || size & 1 || reg & 1 || reg < 0x76C || reg > 0xD7FA) ++ return false; ++ ++ if (size == 2) { ++ if (reg & 2) ++ reg -= 2; ++ else ++ value <<= 16; ++ } ++ ++ /* High registers (clip values) are all 2x 9-bit */ ++ if (reg >= 0xD7D8) ++ return !(value & ~0x01FF01FF); ++ ++ /* Early registers follow a repeating pattern */ ++ reg -= 0xD76C; ++ reg >>= 2; ++ return !(value & ~allowed[reg % sizeof(allowed)]); ++} ++ ++static bool validate_dnn_output_setting(u16 reg, uint8_t size, ++ uint32_t value) ++{ ++ /* Only Y_OUT_SIZE for Input Tensor / Output Tensor is configurable from ++ * userspace ++ */ ++ return (size == 2) && (value < 2046) && ++ ((reg == CCI_REG_ADDR(IMX500_REG_DD_CH07_Y_OUT_SIZE)) || ++ (reg == CCI_REG_ADDR(IMX500_REG_DD_CH08_Y_OUT_SIZE))); ++} ++ ++static bool __must_check ++imx500_validate_inference_register(const struct cci_reg_sequence *reg) ++{ ++ unsigned int i; ++ ++ static bool (*const checks[])(uint16_t, uint8_t, uint32_t) = { ++ validate_normalization_yuv, ++ validate_bayer_rgb_normalization, ++ validate_normalization_registers, ++ validate_image_format_selection, ++ validate_yc_conversion_factor, ++ validate_dnn_output_setting, ++ }; ++ ++ if (!reg) ++ return false; ++ ++ for (i = 0; i < ARRAY_SIZE(checks); i++) { ++ if (checks[i](CCI_REG_ADDR(reg->reg), ++ CCI_REG_WIDTH_BYTES(reg->reg), reg->val)) ++ return true; ++ } ++ ++ return false; ++} ++ ++static int imx500_set_inference_window(struct imx500 *imx500) ++{ ++ u16 left, top, width, height; ++ ++ if (!imx500->inference_window.width || ++ !imx500->inference_window.height) { ++ width = 4056; ++ height = 3040; ++ left = 0; ++ top = 0; ++ } else { ++ width = min_t(u16, imx500->inference_window.width, 4056); ++ height = min_t(u16, imx500->inference_window.height, 3040); ++ left = min_t(u16, imx500->inference_window.left, 4056); ++ top = min_t(u16, imx500->inference_window.top, 3040); ++ } ++ ++ const struct cci_reg_sequence window_regs[] = { ++ { IMX500_REG_DWP_AP_VC_HOFF, left }, ++ { IMX500_REG_DWP_AP_VC_VOFF, top }, ++ { IMX500_REG_DWP_AP_VC_HSIZE, width }, ++ { IMX500_REG_DWP_AP_VC_VSIZE, height }, ++ }; ++ ++ return cci_multi_reg_write(imx500->regmap, window_regs, ++ ARRAY_SIZE(window_regs), NULL); ++} ++ ++static int imx500_reg_val_write_cbk(void *arg, ++ const struct cci_reg_sequence *reg) ++{ ++ struct imx500 *imx500 = arg; ++ ++ if (!imx500_validate_inference_register(reg)) ++ return -EINVAL; ++ ++ return cci_write(imx500->regmap, reg->reg, reg->val, NULL); ++} ++ + /* Get bayer order based on flip setting. */ + static u32 imx500_get_format_code(struct imx500 *imx500) + { +@@ -745,6 +1222,144 @@ static void imx500_set_default_format(st + imx500->fmt_code = MEDIA_BUS_FMT_SRGGB10_1X10; + } + ++/* -1 on fail, block size on success */ ++static int imx500_validate_fw_block(const char *data, size_t maxlen) ++{ ++ const size_t header_size = 32; ++ static const char header_id[] = { '9', '4', '6', '4' }; ++ ++ const size_t footer_size = 64; ++ static const char footer_id[] = { '3', '6', '9', '5' }; ++ ++ u32 data_size; ++ ++ const char *end = data + maxlen; ++ ++ if (!data) ++ return -1; ++ ++ if (maxlen < header_size) ++ return -1; ++ ++ if (memcmp(data, &header_id, sizeof(header_id))) ++ return -1; ++ ++ /* data_size is size of header + body */ ++ memcpy(&data_size, data + sizeof(header_id), sizeof(data_size)); ++ data_size = ___constant_swab32(data_size); ++ ++ if (end - data_size - footer_size < data) ++ return -1; ++ if (memcmp(data + data_size + footer_size - sizeof(footer_id), ++ &footer_id, sizeof(footer_id))) ++ return -1; ++ ++ return data_size + footer_size; ++} ++ ++/* Parse fw block by block, returning total valid fw size */ ++static size_t imx500_valid_fw_bytes(const u8 *fw, ++ const size_t fw_size) ++{ ++ int i; ++ size_t bytes = 0; ++ ++ const u8 *data = fw; ++ size_t size = fw_size; ++ ++ while ((i = imx500_validate_fw_block(data, size)) > 0) { ++ bytes += i; ++ data += i; ++ size -= i; ++ } ++ ++ return bytes; ++} ++ ++static int imx500_iterate_nw_regs( ++ const u8 *fw, size_t fw_size, void *arg, ++ int (*cbk)(void *arg, const struct cci_reg_sequence *reg)) ++{ ++ struct cpio_data cd = { NULL, 0, "" }; ++ const u8 *read_pos; ++ size_t entries; ++ size_t size; ++ ++ if (!fw || !cbk) ++ return -EINVAL; ++ ++ size = imx500_valid_fw_bytes(fw, fw_size); ++ cd = find_cpio_data("imx500_regs", (void *)(fw + size), ++ fw_size - size, NULL); ++ if (!cd.data || cd.size % 7) ++ return -EINVAL; ++ ++ read_pos = cd.data; ++ entries = cd.size / 7; ++ ++ while (entries--) { ++ struct cci_reg_sequence reg = { 0, 0 }; ++ u16 addr; ++ u8 len; ++ u32 val; ++ int ret; ++ ++ memcpy(&addr, read_pos, sizeof(addr)); ++ read_pos += sizeof(addr); ++ memcpy(&len, read_pos, sizeof(len)); ++ read_pos += sizeof(len); ++ memcpy(&val, read_pos, sizeof(val)); ++ read_pos += sizeof(val); ++ ++ reg.reg = ((len << CCI_REG_WIDTH_SHIFT) | addr); ++ reg.val = val; ++ ++ ret = cbk(arg, ®); ++ if (ret) ++ return ret; ++ } ++ return 0; ++} ++ ++static int imx500_reg_tensor_lines_cbk(void *arg, ++ const struct cci_reg_sequence *reg) ++{ ++ u16 *tensor_lines = arg; ++ ++ if (reg->val < 2046) { ++ switch (reg->reg) { ++ case IMX500_REG_DD_CH07_Y_OUT_SIZE: ++ tensor_lines[0] = reg->val; ++ break; ++ case IMX500_REG_DD_CH08_Y_OUT_SIZE: ++ tensor_lines[1] = reg->val; ++ break; ++ } ++ } ++ ++ return 0; ++} ++ ++static void imx500_calc_inference_lines(struct imx500 *imx500) ++{ ++ u16 tensor_lines[2] = { 0, 0 }; ++ ++ if (!imx500->fw_network) { ++ imx500->num_inference_lines = 0; ++ return; ++ } ++ ++ imx500_iterate_nw_regs(imx500->fw_network, imx500->fw_network_size, ++ tensor_lines, imx500_reg_tensor_lines_cbk); ++ ++ /* Full-res mode, embedded lines are actually slightly shorter than inference ++ * lines 2544 vs 2560 (over-allocate with inf. width) ++ */ ++ imx500->num_inference_lines = IMX500_NUM_KPI_LINES + ++ IMX500_NUM_PQ_LINES + tensor_lines[0] + ++ tensor_lines[1]; ++} ++ + static void imx500_adjust_exposure_range(struct imx500 *imx500) + { + int exposure_max, exposure_def; +@@ -777,6 +1392,99 @@ static int imx500_set_frame_length(struc + imx500->long_exp_shift, NULL); + } + ++/* reg is both input and output: ++ * reg->val is the value we're polling until we're NEQ to ++ * It is then populated with the updated value. ++ */ ++static int __must_check imx500_poll_status_reg(struct imx500 *state, ++ struct cci_reg_sequence *reg, ++ u8 timeout) ++{ ++ u64 read_value; ++ int ret; ++ ++ while (timeout) { ++ ret = cci_read(state->regmap, reg->reg, &read_value, NULL); ++ if (ret) ++ return ret; ++ ++ if (read_value != reg->val) { ++ reg->val = read_value; ++ return 0; ++ } ++ ++ timeout--; ++ mdelay(50); ++ } ++ return -EAGAIN; ++} ++ ++static int imx500_prepare_poll_cmd_reply_sts(struct imx500 *imx500, ++ struct cci_reg_sequence *cmd_reply) ++{ ++ /* Perform single-byte read of 4-byte IMX500_REG_DD_REF_STS register to ++ * target CMD_REPLY_STS_CNT sub-register ++ */ ++ cmd_reply->reg = CCI_REG8(CCI_REG_ADDR(IMX500_REG_DD_REF_STS)); ++ ++ return cci_read(imx500->regmap, cmd_reply->reg, &cmd_reply->val, NULL); ++} ++ ++static int imx500_clear_weights(struct imx500 *imx500) ++{ ++ struct cci_reg_sequence cmd_reply_sts_cnt_reg; ++ u64 imx500_fsm_state; ++ u64 cmd_reply; ++ int ret; ++ ++ static const struct cci_reg_sequence request_clear[] = { ++ { IMX500_REG_DD_ST_TRANS_CMD, ++ IMX500_DD_ST_TRANS_CMD_CLEAR_WEIGHTS }, ++ { IMX500_REG_DD_CMD_INT, IMX500_DD_CMD_INT_ST_TRANS }, ++ }; ++ ++ if (imx500->fsm_state != IMX500_STATE_WITH_NETWORK) ++ return -EINVAL; ++ ++ ret = cci_read(imx500->regmap, IMX500_REG_DD_SYS_STATE, ++ &imx500_fsm_state, NULL); ++ if (ret || imx500_fsm_state != IMX500_DD_SYS_STATE_STANDBY_WITH_NETWORK) ++ return ret ? ret : -EREMOTEIO; ++ ++ ret = imx500_prepare_poll_cmd_reply_sts(imx500, &cmd_reply_sts_cnt_reg); ++ if (ret) ++ return ret; ++ ++ ret = cci_multi_reg_write(imx500->regmap, request_clear, ++ ARRAY_SIZE(request_clear), NULL); ++ if (ret) ++ return ret; ++ ++ ret = imx500_poll_status_reg(imx500, &cmd_reply_sts_cnt_reg, 5); ++ if (ret) ++ return ret; ++ ++ ret = cci_read(imx500->regmap, IMX500_REG_DD_CMD_REPLY_STS, &cmd_reply, ++ NULL); ++ if (ret || cmd_reply != IMX500_DD_CMD_REPLY_STS_TRANS_DONE) ++ return ret ? ret : -EREMOTEIO; ++ ++ imx500->fsm_state = IMX500_STATE_WITHOUT_NETWORK; ++ imx500->network_written = false; ++ return 0; ++} ++ ++static void imx500_clear_fw_network(struct imx500 *imx500) ++{ ++ /* Remove any previous firmware blob. */ ++ if (imx500->fw_network) ++ vfree(imx500->fw_network); ++ ++ imx500->fw_network = NULL; ++ imx500->network_written = false; ++ imx500->fw_progress = 0; ++} ++ + static int imx500_set_ctrl(struct v4l2_ctrl *ctrl) + { + struct imx500 *imx500 = +@@ -784,6 +1492,53 @@ static int imx500_set_ctrl(struct v4l2_c + struct i2c_client *client = v4l2_get_subdevdata(&imx500->sd); + int ret = 0; + ++ if (ctrl->id == V4L2_CID_USER_IMX500_NETWORK_FW_FD) { ++ /* Reset state of the control. */ ++ if (ctrl->val < 0) { ++ return 0; ++ } else if (ctrl->val == S32_MAX) { ++ ctrl->val = -1; ++ if (pm_runtime_get_if_in_use(&client->dev) == 0) ++ return 0; ++ ++ if (imx500->network_written) ++ ret = imx500_clear_weights(imx500); ++ imx500_clear_fw_network(imx500); ++ ++ pm_runtime_mark_last_busy(&client->dev); ++ pm_runtime_put_autosuspend(&client->dev); ++ ++ return ret; ++ } ++ ++ imx500_clear_fw_network(imx500); ++ ret = kernel_read_file_from_fd(ctrl->val, 0, ++ (void **)&imx500->fw_network, INT_MAX, ++ &imx500->fw_network_size, ++ 1); ++ /* ++ * Back to reset state, the FD cannot be considered valid after ++ * this IOCTL completes. ++ */ ++ ctrl->val = -1; ++ ++ if (ret < 0) { ++ dev_err(&client->dev, "%s failed to read fw image: %d\n", ++ __func__, ret); ++ imx500_clear_fw_network(imx500); ++ return ret; ++ } ++ if (ret != imx500->fw_network_size) { ++ dev_err(&client->dev, "%s read fw image size mismatich: got %u, expected %zu\n", ++ __func__, ret, imx500->fw_network_size); ++ imx500_clear_fw_network(imx500); ++ return -EIO; ++ } ++ ++ imx500_calc_inference_lines(imx500); ++ return 0; ++ } ++ + /* + * The VBLANK control may change the limits of usable exposure, so check + * and adjust if necessary. +@@ -831,6 +1586,11 @@ static int imx500_set_ctrl(struct v4l2_c + cci_write(imx500->regmap, IMX500_REG_COLOUR_BALANCE_R, + ctrl->p_new.p_u32[3], &ret); + break; ++ case V4L2_CID_USER_IMX500_INFERENCE_WINDOW: ++ memcpy(&imx500->inference_window, ctrl->p_new.p_u32, ++ sizeof(struct v4l2_rect)); ++ ret = imx500_set_inference_window(imx500); ++ break; + default: + dev_info(&client->dev, + "ctrl(id:0x%x,val:0x%x) is not handled\n", ctrl->id, +@@ -870,10 +1630,17 @@ static int imx500_enum_mbus_code(struct + if (code->pad >= NUM_PADS) + return -EINVAL; + +- if (code->index != 0) +- return -EINVAL; ++ if (code->pad == IMAGE_PAD) { ++ if (code->index != 0) ++ return -EINVAL; + +- code->code = imx500_get_format_code(imx500); ++ code->code = imx500_get_format_code(imx500); ++ } else { ++ if (code->index > 0) ++ return -EINVAL; ++ ++ code->code = MEDIA_BUS_FMT_SENSOR_DATA; ++ } + + return 0; + } +@@ -887,19 +1654,31 @@ static int imx500_enum_frame_size(struct + if (fse->pad >= NUM_PADS) + return -EINVAL; + +- const struct imx500_mode *mode_list = imx500_supported_modes; +- unsigned int num_modes = ARRAY_SIZE(imx500_supported_modes); +- +- if (fse->index >= num_modes) +- return -EINVAL; +- +- if (fse->code != imx500_get_format_code(imx500)) +- return -EINVAL; ++ if (fse->pad == IMAGE_PAD) { ++ const struct imx500_mode *mode_list = imx500_supported_modes; ++ unsigned int num_modes = ARRAY_SIZE(imx500_supported_modes); ++ ++ if (fse->index >= num_modes) ++ return -EINVAL; ++ ++ if (fse->code != imx500_get_format_code(imx500)) ++ return -EINVAL; ++ ++ fse->min_width = mode_list[fse->index].width; ++ fse->max_width = fse->min_width; ++ fse->min_height = mode_list[fse->index].height; ++ fse->max_height = fse->min_height; ++ } else { ++ if (fse->code != MEDIA_BUS_FMT_SENSOR_DATA || fse->index > 0) ++ return -EINVAL; + +- fse->min_width = mode_list[fse->index].width; +- fse->max_width = fse->min_width; +- fse->min_height = mode_list[fse->index].height; +- fse->max_height = fse->min_height; ++ fse->min_width = IMX500_MAX_EMBEDDED_SIZE + ++ imx500->num_inference_lines * ++ IMX500_INFERENCE_LINE_WIDTH; ++ fse->max_width = fse->min_width; ++ fse->min_height = 1; ++ fse->max_height = fse->min_height; ++ } + + return 0; + } +@@ -920,6 +1699,17 @@ static void imx500_update_image_pad_form + V4L2_MAP_XFER_FUNC_DEFAULT(fmt->format.colorspace); + } + ++static void imx500_update_metadata_pad_format(const struct imx500 *imx500, ++ struct v4l2_subdev_format *fmt) ++{ ++ fmt->format.width = ++ IMX500_MAX_EMBEDDED_SIZE + ++ imx500->num_inference_lines * IMX500_INFERENCE_LINE_WIDTH; ++ fmt->format.height = 1; ++ fmt->format.code = MEDIA_BUS_FMT_SENSOR_DATA; ++ fmt->format.field = V4L2_FIELD_NONE; ++} ++ + static int imx500_get_pad_format(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_format *fmt) +@@ -935,11 +1725,18 @@ static int imx500_get_pad_format(struct + struct v4l2_mbus_framefmt *try_fmt = v4l2_subdev_get_try_format( + &imx500->sd, sd_state, fmt->pad); + /* update the code which could change due to vflip or hflip */ +- try_fmt->code = imx500_get_format_code(imx500); ++ try_fmt->code = fmt->pad == IMAGE_PAD ? ++ imx500_get_format_code(imx500) : ++ MEDIA_BUS_FMT_SENSOR_DATA; + fmt->format = *try_fmt; + } else { +- imx500_update_image_pad_format(imx500, imx500->mode, fmt); +- fmt->format.code = imx500_get_format_code(imx500); ++ if (fmt->pad == IMAGE_PAD) { ++ imx500_update_image_pad_format(imx500, imx500->mode, ++ fmt); ++ fmt->format.code = imx500_get_format_code(imx500); ++ } else { ++ imx500_update_metadata_pad_format(imx500, fmt); ++ } + } + + mutex_unlock(&imx500->mutex); +@@ -1000,22 +1797,35 @@ static int imx500_set_pad_format(struct + + mutex_lock(&imx500->mutex); + +- const struct imx500_mode *mode_list = imx500_supported_modes; +- unsigned int num_modes = ARRAY_SIZE(imx500_supported_modes); ++ if (fmt->pad == IMAGE_PAD) { ++ const struct imx500_mode *mode_list = imx500_supported_modes; ++ unsigned int num_modes = ARRAY_SIZE(imx500_supported_modes); + +- /* Bayer order varies with flips */ +- fmt->format.code = imx500_get_format_code(imx500); ++ /* Bayer order varies with flips */ ++ fmt->format.code = imx500_get_format_code(imx500); + +- mode = v4l2_find_nearest_size(mode_list, num_modes, width, height, +- fmt->format.width, fmt->format.height); +- imx500_update_image_pad_format(imx500, mode, fmt); +- if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { +- framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); +- *framefmt = fmt->format; +- } else if (imx500->mode != mode) { +- imx500->mode = mode; +- imx500->fmt_code = fmt->format.code; +- imx500_set_framing_limits(imx500); ++ mode = v4l2_find_nearest_size(mode_list, num_modes, width, ++ height, fmt->format.width, ++ fmt->format.height); ++ imx500_update_image_pad_format(imx500, mode, fmt); ++ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { ++ framefmt = v4l2_subdev_get_try_format(sd, sd_state, ++ fmt->pad); ++ *framefmt = fmt->format; ++ } else if (imx500->mode != mode) { ++ imx500->mode = mode; ++ imx500->fmt_code = fmt->format.code; ++ imx500_set_framing_limits(imx500); ++ } ++ } else { ++ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { ++ framefmt = v4l2_subdev_get_try_format(sd, sd_state, ++ fmt->pad); ++ *framefmt = fmt->format; ++ } else { ++ /* Only one embedded data mode is supported */ ++ imx500_update_metadata_pad_format(imx500, fmt); ++ } + } + + mutex_unlock(&imx500->mutex); +@@ -1074,6 +1884,243 @@ static int imx500_get_selection(struct v + return -EINVAL; + } + ++static int __must_check imx500_spi_write(struct imx500 *state, const u8 *data, ++ size_t size) ++{ ++ if (size % 4 || size > ONE_MIB) ++ return -EINVAL; ++ ++ if (!state->spi_device) ++ return -ENODEV; ++ ++ return spi_write(state->spi_device, data, size); ++} ++ ++/* Moves the IMX500 internal state machine between states or updates. ++ * ++ * Prerequisites: Sensor is powered on and not currently streaming ++ */ ++static int imx500_state_transition(struct imx500 *imx500, const u8 *fw, ++ size_t fw_size, enum imx500_image_type type, ++ bool update) ++{ ++ struct i2c_client *client = v4l2_get_subdevdata(&imx500->sd); ++ struct cci_reg_sequence cmd_reply_sts_cnt_reg; ++ size_t valid_size; ++ int ret; ++ u64 tmp; ++ ++ if (!imx500 || !fw || type >= TYPE_MAX) ++ return -EINVAL; ++ ++ if (!update && (int)type != (int)imx500->fsm_state) ++ return -EINVAL; ++ ++ /* Validate firmware */ ++ valid_size = imx500_valid_fw_bytes(fw, fw_size); ++ if (!valid_size) ++ return -EINVAL; ++ ++ ret = imx500_prepare_poll_cmd_reply_sts(imx500, &cmd_reply_sts_cnt_reg); ++ if (ret) ++ return ret; ++ ++ struct cci_reg_sequence common_regs[] = { ++ { IMX500_REG_DD_FLASH_TYPE, 0x02 }, ++ { IMX500_REG_DD_LOAD_MODE, IMX500_DD_LOAD_MODE_AP }, ++ { IMX500_REG_DD_IMAGE_TYPE, type }, ++ { IMX500_REG_DD_DOWNLOAD_DIV_NUM, (valid_size - 1) / ONE_MIB }, ++ { IMX500_REG_DD_DOWNLOAD_FILE_SIZE, valid_size }, ++ }; ++ ++ struct cci_reg_sequence state_transition_regs[] = { ++ { IMX500_REG_DD_ST_TRANS_CMD, type }, ++ { IMX500_REG_DD_CMD_INT, IMX500_DD_CMD_INT_ST_TRANS }, ++ }; ++ ++ struct cci_reg_sequence update_regs[] = { ++ { IMX500_REG_DD_UPDATE_CMD, IMX500_DD_UPDATE_CMD_SRAM }, ++ { IMX500_REG_DD_CMD_INT, IMX500_DD_CMD_INT_UPDATE }, ++ }; ++ ++ ret = cci_multi_reg_write(imx500->regmap, common_regs, ++ ARRAY_SIZE(common_regs), NULL); ++ ++ cci_multi_reg_write(imx500->regmap, ++ update ? update_regs : state_transition_regs, 2, ++ &ret); ++ if (ret) ++ return ret; ++ ++ /* Poll CMD_REPLY_STS_CNT until a response is available */ ++ ret = imx500_poll_status_reg(imx500, &cmd_reply_sts_cnt_reg, 5); ++ if (ret) { ++ dev_err(&client->dev, "DD_REF_STS register did not update\n"); ++ return ret; ++ } ++ ++ /* Read response to state transition / update request */ ++ ret = cci_read(imx500->regmap, IMX500_REG_DD_CMD_REPLY_STS, &tmp, NULL); ++ if (ret || tmp != (update ? IMX500_DD_CMD_REPLY_STS_UPDATE_READY : ++ IMX500_DD_CMD_REPLY_STS_TRANS_READY)) ++ return ret ? ret : -EBUSY; ++ ++ imx500->fw_stage = type; ++ imx500->fw_progress = 0; ++ ++ for (size_t i = 0; i <= valid_size / ONE_MIB; i++) { ++ const u8 *data = fw + (i * ONE_MIB); ++ size_t size = valid_size - (i * ONE_MIB); ++ struct cci_reg_sequence download_sts_reg = { ++ IMX500_REG_DD_DOWNLOAD_STS, ++ IMX500_DD_DOWNLOAD_STS_DOWNLOADING, ++ }; ++ ++ /* Calculate SPI xfer size avoiding 0-sized TXNs */ ++ size = min_t(size_t, size, ONE_MIB); ++ if (!size) ++ break; ++ ++ /* Poll until device is ready for download */ ++ ret = imx500_poll_status_reg(imx500, &download_sts_reg, 100); ++ if (ret) { ++ dev_err(&client->dev, ++ "DD_DOWNLOAD_STS was never ready\n"); ++ return ret; ++ } ++ ++ /* Do SPI transfer */ ++ ret = imx500_spi_write(imx500, data, size); ++ imx500->fw_progress += size; ++ ++ if (ret < 0) ++ return ret; ++ } ++ ++ /* Poll until another response is available */ ++ ret = imx500_poll_status_reg(imx500, &cmd_reply_sts_cnt_reg, 5); ++ if (ret) { ++ dev_err(&client->dev, ++ "DD_REF_STS register did not update after SPI write(s)\n"); ++ return ret; ++ } ++ ++ /* Verify that state transition / update completed successfully */ ++ ret = cci_read(imx500->regmap, IMX500_REG_DD_CMD_REPLY_STS, &tmp, NULL); ++ if (ret || tmp != (update ? IMX500_DD_CMD_REPLY_STS_UPDATE_DONE : ++ IMX500_DD_CMD_REPLY_STS_TRANS_DONE)) ++ return ret ? ret : -EREMOTEIO; ++ ++ if (!update && imx500->fsm_state < IMX500_STATE_WITH_NETWORK) ++ imx500->fsm_state++; ++ ++ imx500->fw_progress = fw_size; ++ ++ return 0; ++} ++ ++static int imx500_transition_to_standby_wo_network(struct imx500 *imx500) ++{ ++ struct i2c_client *client = v4l2_get_subdevdata(&imx500->sd); ++ const struct firmware *firmware; ++ u64 fw_ver; ++ int ret; ++ ++ firmware = imx500->fw_loader; ++ ret = imx500_state_transition(imx500, firmware->data, firmware->size, ++ TYPE_LOADER, false); ++ if (ret) { ++ dev_err(&client->dev, "%s: failed to load loader firmware\n", ++ __func__); ++ return ret; ++ } ++ ++ firmware = imx500->fw_main; ++ ret = imx500_state_transition(imx500, firmware->data, firmware->size, ++ TYPE_MAIN, false); ++ if (ret) { ++ dev_err(&client->dev, "%s: failed to load main firmware\n", ++ __func__); ++ return ret; ++ } ++ ++ ret = cci_read(imx500->regmap, IMX500_REG_MAIN_FW_VERSION, &fw_ver, ++ NULL); ++ if (ret) { ++ dev_err(&client->dev, ++ "%s: could not read main firmware version\n", __func__); ++ return ret; ++ } ++ ++ dev_info(&client->dev, ++ "main firmware version: %llu%llu.%llu%llu.%llu%llu\n", ++ (fw_ver >> 20) & 0xF, (fw_ver >> 16) & 0xF, ++ (fw_ver >> 12) & 0xF, (fw_ver >> 8) & 0xF, (fw_ver >> 4) & 0xF, ++ fw_ver & 0xF); ++ ++ ret = cci_multi_reg_write(imx500->regmap, metadata_output, ++ ARRAY_SIZE(metadata_output), NULL); ++ if (ret) { ++ dev_err(&client->dev, ++ "%s: failed to configure MIPI output for DNN\n", ++ __func__); ++ return ret; ++ } ++ ++ ret = cci_multi_reg_write(imx500->regmap, dnn_regs, ++ ARRAY_SIZE(dnn_regs), NULL); ++ if (ret) { ++ dev_err(&client->dev, "%s: unable to write DNN regs\n", ++ __func__); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int imx500_transition_to_network(struct imx500 *imx500) ++{ ++ struct i2c_client *client = v4l2_get_subdevdata(&imx500->sd); ++ u64 imx500_fsm_state; ++ int ret; ++ ++ ret = imx500_iterate_nw_regs(imx500->fw_network, ++ imx500->fw_network_size, imx500, ++ imx500_reg_val_write_cbk); ++ if (ret) { ++ dev_err(&client->dev, ++ "%s: unable to apply register writes from firmware\n", ++ __func__); ++ return ret; ++ } ++ ++ /* Read IMX500 state to determine whether transition or update is required */ ++ ret = cci_read(imx500->regmap, IMX500_REG_DD_SYS_STATE, ++ &imx500_fsm_state, NULL); ++ if (ret || imx500_fsm_state & 1) ++ return ret ? ret : -EREMOTEIO; ++ ++ ret = imx500_state_transition( ++ imx500, imx500->fw_network, imx500->fw_network_size, ++ TYPE_NW_WEIGHTS, ++ imx500_fsm_state == IMX500_DD_SYS_STATE_STANDBY_WITH_NETWORK); ++ if (ret) { ++ dev_err(&client->dev, "%s: failed to load network weights\n", ++ __func__); ++ return ret; ++ } ++ ++ /* Select network 0 */ ++ ret = cci_write(imx500->regmap, CCI_REG8(0xD701), 0, NULL); ++ if (ret) { ++ dev_err(&client->dev, "%s: failed to select network 0\n", ++ __func__); ++ return ret; ++ } ++ ++ return ret; ++} ++ + /* Start streaming */ + static int imx500_start_streaming(struct imx500 *imx500) + { +@@ -1086,7 +2133,8 @@ static int imx500_start_streaming(struct + return ret; + + ret = cci_write(imx500->regmap, IMX500_REG_IMAGE_ONLY_MODE, +- IMX500_IMAGE_ONLY_TRUE, ++ imx500->fw_network ? IMX500_IMAGE_ONLY_FALSE : ++ IMX500_IMAGE_ONLY_TRUE, + NULL); + if (ret) { + dev_err(&client->dev, "%s failed to set image mode\n", +@@ -1094,6 +2142,30 @@ static int imx500_start_streaming(struct + return ret; + } + ++ /* Acquire loader and main firmware if needed */ ++ if (imx500->fw_network) { ++ if (!imx500->fw_loader) { ++ ret = request_firmware(&imx500->fw_loader, ++ "imx500_loader.fpk", ++ &client->dev); ++ if (ret) { ++ dev_err(&client->dev, ++ "Unable to acquire firmware loader\n"); ++ return ret; ++ } ++ } ++ if (!imx500->fw_main) { ++ ret = request_firmware(&imx500->fw_main, ++ "imx500_firmware.fpk", ++ &client->dev); ++ if (ret) { ++ dev_err(&client->dev, ++ "Unable to acquire main firmware\n"); ++ return ret; ++ } ++ } ++ } ++ + if (!imx500->common_regs_written) { + ret = cci_multi_reg_write(imx500->regmap, mode_common_regs, + ARRAY_SIZE(mode_common_regs), NULL); +@@ -1107,6 +2179,38 @@ static int imx500_start_streaming(struct + imx500->common_regs_written = true; + } + ++ if (imx500->fw_network && !imx500->loader_and_main_written) { ++ ret = imx500_transition_to_standby_wo_network(imx500); ++ if (ret) { ++ dev_err(&client->dev, ++ "%s failed to transition from program empty state\n", ++ __func__); ++ return ret; ++ } ++ imx500->loader_and_main_written = true; ++ } ++ ++ if (imx500->fw_network && !imx500->network_written) { ++ ret = imx500_transition_to_network(imx500); ++ if (ret) { ++ dev_err(&client->dev, ++ "%s failed to transition to network loaded\n", ++ __func__); ++ return ret; ++ } ++ imx500->network_written = true; ++ } ++ ++ /* Enable DNN */ ++ if (imx500->fw_network) { ++ ret = cci_write(imx500->regmap, CCI_REG8(0xD100), 4, NULL); ++ if (ret) { ++ dev_err(&client->dev, "%s failed to enable DNN\n", ++ __func__); ++ return ret; ++ } ++ } ++ + /* Apply default values of current mode */ + reg_list = &imx500->mode->reg_list; + ret = cci_multi_reg_write(imx500->regmap, reg_list->regs, +@@ -1141,6 +2245,11 @@ static void imx500_stop_streaming(struct + if (ret) + dev_err(&client->dev, "%s failed to set stream\n", __func__); + ++ /* Disable DNN */ ++ ret = cci_write(imx500->regmap, CCI_REG8(0xD100), 0, NULL); ++ if (ret) ++ dev_err(&client->dev, "%s failed to disable DNN\n", __func__); ++ + pm_runtime_mark_last_busy(&client->dev); + pm_runtime_put_autosuspend(&client->dev); + } +@@ -1173,6 +2282,7 @@ static int imx500_set_stream(struct v4l2 + /* vflip and hflip cannot change during streaming */ + __v4l2_ctrl_grab(imx500->vflip, enable); + __v4l2_ctrl_grab(imx500->hflip, enable); ++ __v4l2_ctrl_grab(imx500->network_fw_ctrl, enable); + + mutex_unlock(&imx500->mutex); + +@@ -1247,7 +2357,10 @@ static int imx500_power_off(struct devic + regulator_bulk_disable(IMX500_NUM_SUPPLIES, imx500->supplies); + + /* Force reprogramming of the common registers when powered up again. */ ++ imx500->fsm_state = IMX500_STATE_RESET; + imx500->common_regs_written = false; ++ imx500->loader_and_main_written = false; ++ imx500_clear_fw_network(imx500); + + return 0; + } +@@ -1317,6 +2430,36 @@ static const s64 imx500_link_freq_menu[] + IMX500_DEFAULT_LINK_FREQ, + }; + ++/* Custom control for inference window */ ++static const struct v4l2_ctrl_config inf_window_ctrl = { ++ .name = "IMX500 Inference Windows", ++ .id = V4L2_CID_USER_IMX500_INFERENCE_WINDOW, ++ .dims[0] = 4, ++ .ops = &imx500_ctrl_ops, ++ .type = V4L2_CTRL_TYPE_U32, ++ .elem_size = sizeof(u32), ++ .flags = V4L2_CTRL_FLAG_EXECUTE_ON_WRITE | ++ V4L2_CTRL_FLAG_HAS_PAYLOAD, ++ .def = 0, ++ .min = 0x00, ++ .max = 4032, ++ .step = 1, ++}; ++ ++/* Custom control for network firmware file FD */ ++static const struct v4l2_ctrl_config network_fw_fd = { ++ .name = "IMX500 Network Firmware File FD", ++ .id = V4L2_CID_USER_IMX500_NETWORK_FW_FD, ++ .ops = &imx500_ctrl_ops, ++ .type = V4L2_CTRL_TYPE_INTEGER, ++ .flags = V4L2_CTRL_FLAG_EXECUTE_ON_WRITE | ++ V4L2_CTRL_FLAG_WRITE_ONLY, ++ .min = -1, ++ .max = S32_MAX, ++ .step = 1, ++ .def = -1, ++}; ++ + /* Initialize control handlers */ + static int imx500_init_controls(struct imx500 *imx500) + { +@@ -1376,6 +2519,9 @@ static int imx500_init_controls(struct i + imx500->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; + + v4l2_ctrl_new_custom(ctrl_hdlr, &imx500_notify_gains_ctrl, NULL); ++ v4l2_ctrl_new_custom(ctrl_hdlr, &inf_window_ctrl, NULL); ++ imx500->network_fw_ctrl = ++ v4l2_ctrl_new_custom(ctrl_hdlr, &network_fw_fd, NULL); + + if (ctrl_hdlr->error) { + ret = ctrl_hdlr->error; +@@ -1459,12 +2605,35 @@ error_out: + return ret; + } + ++static int fw_progress_show(struct seq_file *s, void *data) ++{ ++ struct imx500 *imx500 = s->private; ++ ++ seq_printf(s, "%d %zu %zu\n", imx500->fw_stage, imx500->fw_progress, ++ imx500->fw_network_size); ++ return 0; ++} ++DEFINE_SHOW_ATTRIBUTE(fw_progress); ++ + static int imx500_probe(struct i2c_client *client) + { + struct device *dev = &client->dev; ++ struct spi_device *spi = NULL; ++ char debugfs_name[128]; + struct imx500 *imx500; + int ret; + ++ struct device_node *spi_node = of_parse_phandle(dev->of_node, "spi", 0); ++ ++ if (spi_node) { ++ struct device *tmp = ++ bus_find_device_by_of_node(&spi_bus_type, spi_node); ++ of_node_put(spi_node); ++ spi = tmp ? to_spi_device(tmp) : NULL; ++ if (!spi) ++ return -EPROBE_DEFER; ++ } ++ + imx500 = devm_kzalloc(&client->dev, sizeof(*imx500), GFP_KERNEL); + if (!imx500) + return -ENOMEM; +@@ -1474,6 +2643,8 @@ static int imx500_probe(struct i2c_clien + return dev_err_probe(dev, PTR_ERR(imx500->regmap), + "failed to initialise CCI\n"); + ++ imx500->spi_device = spi; ++ + v4l2_i2c_subdev_init(&imx500->sd, client, &imx500_subdev_ops); + + /* Check the hardware configuration in device tree */ +@@ -1534,10 +2705,10 @@ static int imx500_probe(struct i2c_clien + imx500->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; + + /* Initialize source pads */ +- imx500->pad.flags = MEDIA_PAD_FL_SOURCE; ++ imx500->pad[IMAGE_PAD].flags = MEDIA_PAD_FL_SOURCE; ++ imx500->pad[METADATA_PAD].flags = MEDIA_PAD_FL_SOURCE; + +- ret = media_entity_pads_init(&imx500->sd.entity, NUM_PADS, +- &imx500->pad); ++ ret = media_entity_pads_init(&imx500->sd.entity, NUM_PADS, imx500->pad); + if (ret) { + dev_err(dev, "failed to init entity pads: %d\n", ret); + goto error_handler_free; +@@ -1549,6 +2720,12 @@ static int imx500_probe(struct i2c_clien + goto error_media_entity; + } + ++ snprintf(debugfs_name, sizeof(debugfs_name), "imx500-fw:%s", ++ dev_name(dev)); ++ imx500->debugfs = debugfs_create_dir(debugfs_name, NULL); ++ debugfs_create_file("fw_progress", 0444, imx500->debugfs, imx500, ++ &fw_progress_fops); ++ + pm_runtime_mark_last_busy(&client->dev); + pm_runtime_put_autosuspend(&client->dev); + +@@ -1573,10 +2750,23 @@ static void imx500_remove(struct i2c_cli + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct imx500 *imx500 = to_imx500(sd); + ++ if (imx500->spi_device) ++ put_device(&imx500->spi_device->dev); ++ + v4l2_async_unregister_subdev(sd); + media_entity_cleanup(&sd->entity); + imx500_free_controls(imx500); + ++ if (imx500->fw_loader) ++ release_firmware(imx500->fw_loader); ++ ++ if (imx500->fw_main) ++ release_firmware(imx500->fw_main); ++ ++ imx500->fw_loader = NULL; ++ imx500->fw_main = NULL; ++ imx500_clear_fw_network(imx500); ++ + pm_runtime_disable(&client->dev); + if (!pm_runtime_status_suspended(&client->dev)) + imx500_power_off(&client->dev); +@@ -1603,7 +2793,63 @@ static struct i2c_driver imx500_i2c_driv + .remove = imx500_remove, + }; + +-module_i2c_driver(imx500_i2c_driver); ++static int imx500_spi_probe(struct spi_device *spi) ++{ ++ int result; ++ ++ spi->bits_per_word = 8; ++ spi->max_speed_hz = 35000000; ++ spi->mode = SPI_MODE_3; ++ ++ result = spi_setup(spi); ++ if (result < 0) ++ return dev_err_probe(&spi->dev, result, "spi_setup() failed"); ++ ++ return 0; ++} ++ ++static void imx500_spi_remove(struct spi_device *spi) ++{ ++} ++ ++static const struct spi_device_id imx500_spi_id[] = { ++ { "imx500", 0 }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(spi, imx500_spi_id); ++ ++static struct spi_driver imx500_spi_driver = { ++ .driver = { ++ .name = "imx500", ++ .of_match_table = imx500_dt_ids, ++ }, ++ .probe = imx500_spi_probe, ++ .remove = imx500_spi_remove, ++ .id_table = imx500_spi_id, ++}; ++ ++static int __init imx500_driver_init(void) ++{ ++ int ret; ++ ++ ret = spi_register_driver(&imx500_spi_driver); ++ if (ret) ++ return ret; ++ ++ ret = i2c_add_driver(&imx500_i2c_driver); ++ if (ret) ++ spi_unregister_driver(&imx500_spi_driver); ++ ++ return ret; ++} ++module_init(imx500_driver_init); ++ ++static void __exit imx500_driver_exit(void) ++{ ++ i2c_del_driver(&imx500_i2c_driver); ++ spi_unregister_driver(&imx500_spi_driver); ++} ++module_exit(imx500_driver_exit); + + MODULE_AUTHOR("Naushir Patuck "); + MODULE_DESCRIPTION("Sony IMX500 sensor driver"); +--- a/include/uapi/linux/v4l2-controls.h ++++ b/include/uapi/linux/v4l2-controls.h +@@ -207,6 +207,12 @@ enum v4l2_colorfx { + * We reserve 16 controls for this driver. */ + #define V4L2_CID_USER_BCM2835_ISP_BASE (V4L2_CID_USER_BASE + 0x10e0) + ++/* ++ * The base for IMX500 driver controls. ++ * We reserve 16 controls for this driver. ++ */ ++#define V4L2_CID_USER_IMX500_BASE (V4L2_CID_USER_BASE + 0x2000) ++ + /* MPEG-class control IDs */ + /* The MPEG controls are applicable to all codec controls + * and the 'MPEG' part of the define is historical */ diff --git a/target/linux/bcm27xx/patches-6.6/950-1247-dts-bcm-283x-2712-clocks-as-simple-bus.patch b/target/linux/bcm27xx/patches-6.6/950-1247-dts-bcm-283x-2712-clocks-as-simple-bus.patch new file mode 100644 index 00000000000..ec77dd17c18 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1247-dts-bcm-283x-2712-clocks-as-simple-bus.patch @@ -0,0 +1,41 @@ +From 15cc525406cf311399d182ffcc18711651b7c8b2 Mon Sep 17 00:00:00 2001 +From: Richard Oliver +Date: Fri, 12 Jul 2024 13:32:30 +0100 +Subject: [PATCH 1247/1350] dts: bcm{283x,2712}: /clocks as "simple-bus" + +Make /clocks node compatible with "simple-bus" to ensure that all children +(not just those that are "fixed-clock" compatible) are automatically +probed. + +Signed-off-by: Richard Oliver +--- + arch/arm/boot/dts/broadcom/bcm283x.dtsi | 4 ++++ + arch/arm64/boot/dts/broadcom/bcm2712.dtsi | 4 ++++ + 2 files changed, 8 insertions(+) + +--- a/arch/arm/boot/dts/broadcom/bcm283x.dtsi ++++ b/arch/arm/boot/dts/broadcom/bcm283x.dtsi +@@ -478,6 +478,10 @@ + }; + + clocks { ++ compatible = "simple-bus"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ + /* The oscillator is the root of the clock tree. */ + clk_osc: clk-osc { + compatible = "fixed-clock"; +--- a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi ++++ b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi +@@ -1258,6 +1258,10 @@ + }; + + clocks { ++ compatible = "simple-bus"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ + /* The oscillator is the root of the clock tree. */ + clk_osc: clk-osc { + compatible = "fixed-clock"; diff --git a/target/linux/bcm27xx/patches-6.6/950-1248-dts-Add-AI-Camera-support.patch b/target/linux/bcm27xx/patches-6.6/950-1248-dts-Add-AI-Camera-support.patch new file mode 100644 index 00000000000..4a451480b03 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1248-dts-Add-AI-Camera-support.patch @@ -0,0 +1,389 @@ +From 4113b1097fe40ff3a64ee7a9ade7c258e9ecdb5b Mon Sep 17 00:00:00 2001 +From: Richard Oliver +Date: Mon, 3 Jun 2024 14:10:27 +0100 +Subject: [PATCH 1248/1350] dts: Add 'AI Camera' support + +The AI Camera combines an IMX500 and a RP2040 GPIO bridge on a single +module. The Raspberry Pi camera regulator is used for both IMX500 and +RP2040. SPI, clocks, and reset (required by IMX500) are provided by the +RP2040 GPIO bridge. + +Signed-off-by: Richard Oliver +--- + arch/arm/boot/dts/overlays/Makefile | 2 + + arch/arm/boot/dts/overlays/README | 21 +++ + arch/arm/boot/dts/overlays/imx500-overlay.dts | 119 +++++++++++++++++ + .../boot/dts/overlays/imx500-pi5-overlay.dts | 124 ++++++++++++++++++ + arch/arm/boot/dts/overlays/imx500.dtsi | 28 ++++ + arch/arm/boot/dts/overlays/overlay_map.dts | 10 ++ + .../dts/overlays/rpi-rp2040-gpio-bridge.dtsi | 21 +++ + 7 files changed, 325 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/imx500-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/imx500-pi5-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/imx500.dtsi + create mode 100644 arch/arm/boot/dts/overlays/rpi-rp2040-gpio-bridge.dtsi + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -136,6 +136,8 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + imx378.dtbo \ + imx462.dtbo \ + imx477.dtbo \ ++ imx500.dtbo \ ++ imx500-pi5.dtbo \ + imx519.dtbo \ + imx708.dtbo \ + interludeaudio-analog.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -2818,6 +2818,27 @@ Params: rotation Mounting + sync-sink Configure as vsync sink + + ++Name: imx500 ++Info: Sony IMX500 camera module. ++ Uses Unicam 1, which is the standard camera connector on most Pi ++ variants. ++Load: dtoverlay=imx500,= ++Params: rotation Mounting rotation of the camera sensor (0 or ++ 180, default 0) ++ orientation Sensor orientation (0 = front, 1 = rear, ++ 2 = external, default external) ++ media-controller Configure use of Media Controller API for ++ configuring the sensor (default on) ++ cam0 Adopt the default configuration for CAM0 on a ++ Compute Module (CSI0, i2c_vc, and cam0_reg). ++ bypass-cache Do save blocks of data to flash when using ++ rp2040-gpio-bridge for SPI transfers. ++ ++ ++Name: imx500-pi5 ++Info: See imx500 (this is the Pi 5 version) ++ ++ + Name: imx519 + Info: Sony IMX519 camera module. + Uses Unicam 1, which is the standard camera connector on most Pi +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/imx500-overlay.dts +@@ -0,0 +1,119 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++// Definitions for IMX500 camera module on VC I2C bus ++/dts-v1/; ++/plugin/; ++ ++#include ++ ++/{ ++ compatible = "brcm,bcm2835"; ++ ++ fragment@0 { ++ target = <&i2c0if>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c0mux>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ reg_frag: fragment@2 { ++ target = <&cam1_reg>; ++ cam_reg: __overlay__ { ++ startup-delay-us = <300000>; ++ }; ++ }; ++ ++ i2c_frag: fragment@100 { ++ target = <&i2c_csi_dsi>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ #include "imx500.dtsi" ++ #include "rpi-rp2040-gpio-bridge.dtsi" ++ }; ++ }; ++ ++ csi_frag: fragment@101 { ++ target = <&csi1>; ++ csi: __overlay__ { ++ status = "okay"; ++ brcm,media-controller; ++ ++ port { ++ csi_ep: endpoint { ++ remote-endpoint = <&cam_endpoint>; ++ clock-lanes = <0>; ++ data-lanes = <1 2>; ++ clock-noncontinuous; ++ }; ++ }; ++ }; ++ }; ++ ++ spi_frag: fragment@102 { ++ target = <&spi_bridgedev0>; ++ __overlay__ { ++ compatible = "sony,imx500"; ++ }; ++ }; ++ ++ chosen_frag: fragment@103 { ++ target = <&chosen>; ++ __overlay__ { ++ core_freq_fixed; ++ }; ++ }; ++ ++ clocks_frag: fragment@104 { ++ target-path = "/clocks"; ++ __overlay__ { ++ clk_aicam: clk-aicam { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <24000000>; ++ }; ++ ++ clk_aicam_gated: clk-aicam-gated { ++ compatible = "gpio-gate-clock"; ++ clocks = <&clk_aicam>; ++ #clock-cells = <0>; ++ enable-gpios = <&spi_bridge 21 GPIO_ACTIVE_HIGH>; ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ rotation = <&cam_node>,"rotation:0"; ++ orientation = <&cam_node>,"orientation:0"; ++ media-controller = <&csi>,"brcm,media-controller?"; ++ cam0 = <&i2c_frag>, "target:0=",<&i2c_csi_dsi0>, ++ <&csi_frag>, "target:0=",<&csi0>, ++ <&spi_bridge>, "power-supply:0=",<&cam0_reg>, ++ <®_frag>, "target:0=",<&cam0_reg>, ++ <&cam_node>, "VANA-supply:0=",<&cam0_reg>; ++ bypass-cache = <&spi_bridge>,"bypass-cache?"; ++ }; ++}; ++ ++&cam_node { ++ status = "okay"; ++ reset-gpios = <&spi_bridge 20 GPIO_ACTIVE_HIGH>; ++ clocks = <&clk_aicam_gated>; ++ spi = <&spi_bridgedev0>; ++}; ++ ++&spi_bridge { ++ status = "okay"; ++}; ++ ++&cam_endpoint { ++ remote-endpoint = <&csi_ep>; ++}; +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/imx500-pi5-overlay.dts +@@ -0,0 +1,124 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++// Definitions for IMX500 camera module on VC I2C bus ++/dts-v1/; ++/plugin/; ++ ++#include ++ ++/{ ++ compatible = "brcm,bcm2712"; ++ ++ fragment@0 { ++ target = <&i2c0if>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c0mux>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ reg_frag: fragment@2 { ++ target = <&cam1_reg>; ++ cam_reg: __overlay__ { ++ startup-delay-us = <300000>; ++ }; ++ }; ++ ++ i2c_frag: fragment@100 { ++ target = <&i2c_csi_dsi>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ #include "imx500.dtsi" ++ #include "rpi-rp2040-gpio-bridge.dtsi" ++ }; ++ }; ++ ++ csi_frag: fragment@101 { ++ target = <&csi1>; ++ csi: __overlay__ { ++ status = "okay"; ++ brcm,media-controller; ++ ++ port { ++ csi_ep: endpoint { ++ remote-endpoint = <&cam_endpoint>; ++ clock-lanes = <0>; ++ data-lanes = <1 2>; ++ clock-noncontinuous; ++ }; ++ }; ++ }; ++ }; ++ ++ spi_frag: fragment@102 { ++ target = <&spi_bridge>; ++ spi_frag_overlay: __overlay__ { ++ fast_xfer_requires_i2c_lock = <1>; ++ fast_xfer_recv_gpio_base = <11>; ++ fast_xfer-gpios = <&rp1_gpio 40 0>, // CD1_SDA (used as data) ++ <&rp1_gpio 48 0>; // CD1_IO1_MICDAT1 (clock) ++ }; ++ }; ++ ++ spi_bridge_frag: fragment@103 { ++ target = <&spi_bridgedev0>; ++ __overlay__ { ++ compatible = "sony,imx500"; ++ }; ++ }; ++ ++ clocks_frag: fragment@104 { ++ target-path = "/clocks"; ++ __overlay__ { ++ clk_aicam: clk-aicam { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <24000000>; ++ }; ++ ++ clk_aicam_gated: clk-aicam-gated { ++ compatible = "gpio-gate-clock"; ++ clocks = <&clk_aicam>; ++ #clock-cells = <0>; ++ enable-gpios = <&spi_bridge 21 GPIO_ACTIVE_HIGH>; ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ rotation = <&cam_node>,"rotation:0"; ++ orientation = <&cam_node>,"orientation:0"; ++ media-controller = <&csi>,"brcm,media-controller?"; ++ cam0 = <&i2c_frag>, "target:0=",<&i2c_csi_dsi0>, ++ <&csi_frag>, "target:0=",<&csi0>, ++ <&spi_frag_overlay>, "fast_xfer-gpios:4=38", // CD0_SDA (data) ++ <&spi_frag_overlay>, "fast_xfer-gpios:16=35", // CD0_IO1_MICDAT0 (clock) ++ <&spi_bridge>, "power-supply:0=",<&cam0_reg>, ++ <®_frag>, "target:0=",<&cam0_reg>, ++ <&cam_node>, "VANA-supply:0=",<&cam0_reg>; ++ bypass-cache = <&spi_bridge>,"bypass-cache?"; ++ }; ++}; ++ ++&cam_node { ++ status = "okay"; ++ reset-gpios = <&spi_bridge 20 GPIO_ACTIVE_HIGH>; ++ clocks = <&clk_aicam_gated>; ++ spi = <&spi_bridgedev0>; ++}; ++ ++&spi_bridge { ++ status = "okay"; ++}; ++ ++&cam_endpoint { ++ remote-endpoint = <&csi_ep>; ++}; +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/imx500.dtsi +@@ -0,0 +1,28 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++cam_node: imx500@1a { ++ reg = <0x1a>; ++ compatible = "sony,imx500"; ++ status = "disabled"; ++ ++ clocks = <&cam1_clk>; ++ clock-names = "inck"; ++ ++ vana-supply = <&cam1_reg>; /* 2.7v */ ++ vdig-supply = <&cam_dummy_reg>; /* 0.84v */ ++ vif-supply = <&cam_dummy_reg>; /* 1.8v */ ++ ++ reset-gpios = <&gpio 255 GPIO_ACTIVE_HIGH>; ++ ++ rotation = <0>; ++ orientation = <2>; ++ ++ port { ++ cam_endpoint: endpoint { ++ clock-lanes = <0>; ++ data-lanes = <1 2>; ++ clock-noncontinuous; ++ link-frequencies = ++ /bits/ 64 <444000000>; ++ }; ++ }; ++}; +--- a/arch/arm/boot/dts/overlays/overlay_map.dts ++++ b/arch/arm/boot/dts/overlays/overlay_map.dts +@@ -118,6 +118,16 @@ + bcm2711; + }; + ++ imx500 { ++ bcm2835; ++ bcm2711; ++ bcm2712 = "imx500-pi5"; ++ }; ++ ++ imx500-pi5 { ++ bcm2712; ++ }; ++ + lirc-rpi { + deprecated = "use gpio-ir"; + }; +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/rpi-rp2040-gpio-bridge.dtsi +@@ -0,0 +1,21 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++spi_bridge: spi@40 { ++ reg = <0x40>; ++ compatible = "raspberrypi,rp2040-gpio-bridge"; ++ status = "disabled"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ power-supply = <&cam1_reg>; ++ ++ #gpio-cells = <2>; ++ gpio-controller; ++ ++ spi_bridgedev0: spidev@0{ ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <35000000>; ++ }; ++}; diff --git a/target/linux/bcm27xx/patches-6.6/950-1250-media-i2c-imx500-Enable-LED-during-SPI-transfers.patch b/target/linux/bcm27xx/patches-6.6/950-1250-media-i2c-imx500-Enable-LED-during-SPI-transfers.patch new file mode 100644 index 00000000000..cd7da629c09 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1250-media-i2c-imx500-Enable-LED-during-SPI-transfers.patch @@ -0,0 +1,66 @@ +From 62faabb61ae152e8289a00ffb3445f4c47777b33 Mon Sep 17 00:00:00 2001 +From: Richard Oliver +Date: Mon, 3 Jun 2024 16:02:41 +0100 +Subject: [PATCH 1250/1350] media: i2c: imx500: Enable LED during SPI transfers + +The Raspberry Pi 'AI Camera' is equipped with an LED. Enable this LED +during SPI transfers to indicate to the end-user that progress is being +made during large tramsfers. + +Signed-off-by: Richard Oliver +--- + arch/arm/boot/dts/overlays/imx500-overlay.dts | 1 + + arch/arm/boot/dts/overlays/imx500-pi5-overlay.dts | 1 + + drivers/media/i2c/imx500.c | 6 ++++++ + 3 files changed, 8 insertions(+) + +--- a/arch/arm/boot/dts/overlays/imx500-overlay.dts ++++ b/arch/arm/boot/dts/overlays/imx500-overlay.dts +@@ -105,6 +105,7 @@ + + &cam_node { + status = "okay"; ++ led-gpios = <&spi_bridge 19 GPIO_ACTIVE_HIGH>; + reset-gpios = <&spi_bridge 20 GPIO_ACTIVE_HIGH>; + clocks = <&clk_aicam_gated>; + spi = <&spi_bridgedev0>; +--- a/arch/arm/boot/dts/overlays/imx500-pi5-overlay.dts ++++ b/arch/arm/boot/dts/overlays/imx500-pi5-overlay.dts +@@ -110,6 +110,7 @@ + + &cam_node { + status = "okay"; ++ led-gpios = <&spi_bridge 19 GPIO_ACTIVE_HIGH>; + reset-gpios = <&spi_bridge 20 GPIO_ACTIVE_HIGH>; + clocks = <&clk_aicam_gated>; + spi = <&spi_bridgedev0>; +--- a/drivers/media/i2c/imx500.c ++++ b/drivers/media/i2c/imx500.c +@@ -965,6 +965,7 @@ struct imx500 { + struct clk *xclk; + u32 xclk_freq; + ++ struct gpio_desc *led_gpio; + struct gpio_desc *reset_gpio; + struct regulator_bulk_data supplies[IMX500_NUM_SUPPLIES]; + +@@ -1990,7 +1991,10 @@ static int imx500_state_transition(struc + } + + /* Do SPI transfer */ ++ gpiod_set_value_cansleep(imx500->led_gpio, 1); + ret = imx500_spi_write(imx500, data, size); ++ gpiod_set_value_cansleep(imx500->led_gpio, 0); ++ + imx500->fw_progress += size; + + if (ret < 0) +@@ -2670,6 +2674,8 @@ static int imx500_probe(struct i2c_clien + return ret; + } + ++ imx500->led_gpio = devm_gpiod_get_optional(dev, "led", GPIOD_OUT_LOW); ++ + imx500->reset_gpio = + devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); + diff --git a/target/linux/bcm27xx/patches-6.6/950-1251-spi-rp2040-gpio-bridge-add-missing-MD5-dependency.patch b/target/linux/bcm27xx/patches-6.6/950-1251-spi-rp2040-gpio-bridge-add-missing-MD5-dependency.patch new file mode 100644 index 00000000000..f6a27b815f6 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1251-spi-rp2040-gpio-bridge-add-missing-MD5-dependency.patch @@ -0,0 +1,24 @@ +From cc50cdbcf3e8f065bd7798a92689f54578b4169f Mon Sep 17 00:00:00 2001 +From: Richard Oliver +Date: Wed, 24 Jul 2024 15:48:22 +0100 +Subject: [PATCH 1251/1350] spi: rp2040-gpio-bridge: add missing MD5 dependency + +rp2040-gpio-bridge relies on the md5 crypto driver. This dependency +cannot be determined automatically as rp2040-gpio-bridge does not +use any of md5's symbols directly. + +Declare a soft 'pre' dependency on md5 to ensure that it is included and +loaded before rp2040-gpio-bridge. + +Signed-off-by: Richard Oliver +--- + drivers/spi/spi-rp2040-gpio-bridge.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/spi/spi-rp2040-gpio-bridge.c ++++ b/drivers/spi/spi-rp2040-gpio-bridge.c +@@ -1241,3 +1241,4 @@ module_i2c_driver(rp2040_gbdg_driver); + MODULE_AUTHOR("Richard Oliver "); + MODULE_DESCRIPTION("Raspberry Pi RP2040 GPIO Bridge"); + MODULE_LICENSE("GPL"); ++MODULE_SOFTDEP("pre: md5"); diff --git a/target/linux/bcm27xx/patches-6.6/950-1252-drivers-drm-rp1-vec-Increase-width-limit-for-PAL-16-.patch b/target/linux/bcm27xx/patches-6.6/950-1252-drivers-drm-rp1-vec-Increase-width-limit-for-PAL-16-.patch new file mode 100644 index 00000000000..d22b3c025db --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1252-drivers-drm-rp1-vec-Increase-width-limit-for-PAL-16-.patch @@ -0,0 +1,50 @@ +From eab19e7bde679f56241db0c51f94f056fcffd6a9 Mon Sep 17 00:00:00 2001 +From: Nick Hollinghurst +Date: Wed, 4 Sep 2024 19:28:50 +0100 +Subject: [PATCH 1252/1350] drivers: drm: rp1-vec: Increase width limit, for + PAL 16:9 @ 18MHz + +There was no technical reason for the DRM mode's width limit of 848; +increase it to 960 (720*18MHz/13.5MHz) to support ~square pixels on +16:9 screens. Tweak the PAL active window to start slightly earlier. +(The maximum number of visible columns at 18MHz is about 942.) + +Signed-off-by: Nick Hollinghurst +--- + drivers/gpu/drm/rp1/rp1-vec/rp1_vec.c | 4 ++-- + drivers/gpu/drm/rp1/rp1-vec/rp1_vec_hw.c | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/gpu/drm/rp1/rp1-vec/rp1_vec.c ++++ b/drivers/gpu/drm/rp1/rp1-vec/rp1_vec.c +@@ -508,8 +508,8 @@ static int rp1vec_platform_probe(struct + + vec->drm.mode_config.min_width = 256; + vec->drm.mode_config.min_height = 128; +- vec->drm.mode_config.max_width = 848; /* for System E */ +- vec->drm.mode_config.max_height = 738; /* for System E */ ++ vec->drm.mode_config.max_width = 960; /* for "widescreen" @ 18MHz */ ++ vec->drm.mode_config.max_height = 738; /* for System E only */ + vec->drm.mode_config.preferred_depth = 32; + vec->drm.mode_config.prefer_shadow = 0; + vec->drm.mode_config.quirk_addfb_prefer_host_byte_order = true; +--- a/drivers/gpu/drm/rp1/rp1-vec/rp1_vec_hw.c ++++ b/drivers/gpu/drm/rp1/rp1-vec/rp1_vec_hw.c +@@ -195,7 +195,7 @@ static const struct rp1vec_hwmode rp1vec + .misc = 0x00091c01, /* 5-tap FIR, SEQ_EN, 8 fld sync, PAL */ + .nco_freq = 0x0a8262b2cc48c1d1, + .timing_regs = { +- 0x046e0cee, 0x0d8001fb, 0x025c034f, 0x00fd0b84, ++ 0x04660cee, 0x0d8001fb, 0x025c034f, 0x00fd0b84, + 0x026c0270, 0x00000004, 0x00050009, 0x00070135, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00170136, 0x00000000, +@@ -218,7 +218,7 @@ static const struct rp1vec_hwmode rp1vec + .misc = 0x0009dc03, /* 5-tap FIR, SEQ_EN, 4 flds, 8 fld sync, ilace, PAL */ + .nco_freq = 0x0a8262b2cc48c1d1, + .timing_regs = { +- 0x046e0cee, 0x0d8001fb, 0x025c034f, 0x00fd0b84, ++ 0x04660cee, 0x0d8001fb, 0x025c034f, 0x00fd0b84, + 0x026c0270, 0x00000004, 0x00050009, 0x00070135, + 0x013f026d, 0x00060136, 0x0140026e, 0x0150026e, + 0x00180136, 0x026f0017, diff --git a/target/linux/bcm27xx/patches-6.6/950-0058-Revert-Bluetooth-Always-request-for-user-confirmatio.patch b/target/linux/bcm27xx/patches-6.6/950-1255-Revert-Bluetooth-Always-request-for-user-confirmatio.patch similarity index 86% rename from target/linux/bcm27xx/patches-6.6/950-0058-Revert-Bluetooth-Always-request-for-user-confirmatio.patch rename to target/linux/bcm27xx/patches-6.6/950-1255-Revert-Bluetooth-Always-request-for-user-confirmatio.patch index 5e3446d6f13..e549f27d7b3 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0058-Revert-Bluetooth-Always-request-for-user-confirmatio.patch +++ b/target/linux/bcm27xx/patches-6.6/950-1255-Revert-Bluetooth-Always-request-for-user-confirmatio.patch @@ -1,7 +1,7 @@ -From eaeca896d077e9e42866f7f7caae7b62211a0d0d Mon Sep 17 00:00:00 2001 +From d6a12dd8f4e9362f7dd355969dd046adc44b1f47 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 1 Mar 2021 09:12:44 +0000 -Subject: [PATCH 0058/1085] Revert "Bluetooth: Always request for user +Subject: [PATCH 1255/1350] Revert "Bluetooth: Always request for user confirmation for Just Works (LE SC)" This reverts commit ffee202a78c2980688bc5d2f7d56480e69a5e0c9. @@ -24,7 +24,7 @@ Signed-off-by: Phil Elwell --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c -@@ -2215,7 +2215,7 @@ mackey_and_ltk: +@@ -2208,7 +2208,7 @@ mackey_and_ltk: if (err) return SMP_UNSPECIFIED; @@ -33,7 +33,7 @@ Signed-off-by: Phil Elwell if (test_bit(SMP_FLAG_INITIATOR, &smp->flags)) { sc_dhkey_check(smp); SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK); -@@ -2230,9 +2230,6 @@ mackey_and_ltk: +@@ -2223,9 +2223,6 @@ mackey_and_ltk: confirm_hint = 0; confirm: diff --git a/target/linux/bcm27xx/patches-6.6/950-1256-media-i2c-ov5647-Add-control-of-V4L2_CID_HBLANK.patch b/target/linux/bcm27xx/patches-6.6/950-1256-media-i2c-ov5647-Add-control-of-V4L2_CID_HBLANK.patch new file mode 100644 index 00000000000..89c690ca5bf --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1256-media-i2c-ov5647-Add-control-of-V4L2_CID_HBLANK.patch @@ -0,0 +1,126 @@ +From e4c2a7731efcd7abe7554debef783b5358712d6d Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 9 Sep 2024 16:41:12 +0100 +Subject: [PATCH 1256/1350] media: i2c: ov5647: Add control of V4L2_CID_HBLANK + +The driver did expose V4L2_CID_HBLANK, but as a READ_ONLY control. + +The sensor only uses the HTS register to control the line length, +so convert this control to read/write, with the appropriate ranges. +Adopt the old fixed values as the minimum values permitted in each +mode to avoid issues of it not streaming. + +This should allow exposure times up to ~3 seconds (up from ~1sec). + +Signed-off-by: Dave Stevenson +--- + drivers/media/i2c/ov5647.c | 26 +++++++++++++------------- + 1 file changed, 13 insertions(+), 13 deletions(-) + +--- a/drivers/media/i2c/ov5647.c ++++ b/drivers/media/i2c/ov5647.c +@@ -53,6 +53,8 @@ + #define OV5647_REG_AEC_AGC 0x3503 + #define OV5647_REG_GAIN_HI 0x350a + #define OV5647_REG_GAIN_LO 0x350b ++#define OV5647_REG_HTS_HI 0x380c ++#define OV5647_REG_HTS_LO 0x380d + #define OV5647_REG_VTS_HI 0x380e + #define OV5647_REG_VTS_LO 0x380f + #define OV5647_REG_VFLIP 0x3820 +@@ -79,6 +81,8 @@ + #define OV5647_VBLANK_MIN 24 + #define OV5647_VTS_MAX 32767 + ++#define OV5647_HTS_MAX 0x1fff ++ + #define OV5647_EXPOSURE_MIN 4 + #define OV5647_EXPOSURE_STEP 1 + #define OV5647_EXPOSURE_DEFAULT 1000 +@@ -188,8 +192,6 @@ static struct regval_list ov5647_2592x19 + {0x3a19, 0xf8}, + {0x3c01, 0x80}, + {0x3b07, 0x0c}, +- {0x380c, 0x0b}, +- {0x380d, 0x1c}, + {0x3814, 0x11}, + {0x3815, 0x11}, + {0x3708, 0x64}, +@@ -277,8 +279,6 @@ static struct regval_list ov5647_1080p30 + {0x3a19, 0xf8}, + {0x3c01, 0x80}, + {0x3b07, 0x0c}, +- {0x380c, 0x09}, +- {0x380d, 0x70}, + {0x3814, 0x11}, + {0x3815, 0x11}, + {0x3708, 0x64}, +@@ -376,8 +376,6 @@ static struct regval_list ov5647_2x2binn + {0x3809, 0x10}, + {0x380a, 0x03}, + {0x380b, 0xcc}, +- {0x380c, 0x07}, +- {0x380d, 0x68}, + {0x3811, 0x0c}, + {0x3813, 0x06}, + {0x3814, 0x31}, +@@ -451,8 +449,6 @@ static struct regval_list ov5647_640x480 + {0x3a19, 0xf8}, + {0x3c01, 0x80}, + {0x3b07, 0x0c}, +- {0x380c, 0x07}, +- {0x380d, 0x3c}, + {0x3814, 0x35}, + {0x3815, 0x35}, + {0x3708, 0x64}, +@@ -1079,7 +1075,8 @@ static int ov5647_set_pad_fmt(struct v4l + mode->pixel_rate, 1, mode->pixel_rate); + + hblank = mode->hts - mode->format.width; +- __v4l2_ctrl_modify_range(sensor->hblank, hblank, hblank, 1, ++ __v4l2_ctrl_modify_range(sensor->hblank, hblank, ++ OV5647_HTS_MAX - mode->format.width, 1, + hblank); + + vblank = mode->vts - mode->format.height; +@@ -1343,6 +1340,10 @@ static int ov5647_s_ctrl(struct v4l2_ctr + ret = ov5647_write16(sd, OV5647_REG_VTS_HI, + sensor->mode->format.height + ctrl->val); + break; ++ case V4L2_CID_HBLANK: ++ ret = ov5647_write16(sd, OV5647_REG_HTS_HI, ++ sensor->mode->format.width + ctrl->val); ++ break; + case V4L2_CID_TEST_PATTERN: + ret = ov5647_write(sd, OV5647_REG_ISPCTRL3D, + ov5647_test_pattern_val[ctrl->val]); +@@ -1350,7 +1351,6 @@ static int ov5647_s_ctrl(struct v4l2_ctr + + /* Read-only, but we adjust it based on mode. */ + case V4L2_CID_PIXEL_RATE: +- case V4L2_CID_HBLANK: + /* Read-only, but we adjust it based on mode. */ + break; + +@@ -1427,10 +1427,11 @@ static int ov5647_init_controls(struct o + sensor->mode->pixel_rate, 1, + sensor->mode->pixel_rate); + +- /* By default, HBLANK is read only, but it does change per mode. */ + hblank = sensor->mode->hts - sensor->mode->format.width; + sensor->hblank = v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops, +- V4L2_CID_HBLANK, hblank, hblank, 1, ++ V4L2_CID_HBLANK, hblank, ++ OV5647_HTS_MAX - ++ sensor->mode->format.width, 1, + hblank); + + sensor->vblank = v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops, +@@ -1464,7 +1465,6 @@ static int ov5647_init_controls(struct o + goto handler_free; + + sensor->pixel_rate->flags |= V4L2_CTRL_FLAG_READ_ONLY; +- sensor->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; + sensor->sd.ctrl_handler = &sensor->ctrls; + + return 0; diff --git a/target/linux/bcm27xx/patches-6.6/950-1257-drm-vc4-Add-support-for-per-plane-scaling-filter-sel.patch b/target/linux/bcm27xx/patches-6.6/950-1257-drm-vc4-Add-support-for-per-plane-scaling-filter-sel.patch new file mode 100644 index 00000000000..5b3ae3c9101 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1257-drm-vc4-Add-support-for-per-plane-scaling-filter-sel.patch @@ -0,0 +1,170 @@ +From d6a3a3f106010d9576a700148220842cac4c5739 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Thu, 25 Jul 2024 15:42:41 +0100 +Subject: [PATCH 1257/1350] drm/vc4: Add support for per plane scaling filter + selection + +Seeing as the HVS can be configured with regard the scaling filter, +and DRM now supports selecting scaling filters at a per CRTC or +per plane level, we can implement it. + +Default remains as the Mitchell/Netravali filter, but nearest +neighbour is now also implemented. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_drv.h | 1 + + drivers/gpu/drm/vc4/vc4_hvs.c | 14 ++++++++-- + drivers/gpu/drm/vc4/vc4_plane.c | 48 ++++++++++++++++++++++++++------- + 3 files changed, 52 insertions(+), 11 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_drv.h ++++ b/drivers/gpu/drm/vc4/vc4_drv.h +@@ -358,6 +358,7 @@ struct vc4_hvs { + struct work_struct free_dlist_work; + + struct drm_mm_node mitchell_netravali_filter; ++ struct drm_mm_node nearest_neighbour_filter; + + struct debugfs_regset32 regset; + +--- a/drivers/gpu/drm/vc4/vc4_hvs.c ++++ b/drivers/gpu/drm/vc4/vc4_hvs.c +@@ -469,6 +469,9 @@ static int vc4_hvs_debugfs_dlist_allocs( + static const u32 mitchell_netravali_1_3_1_3_kernel[] = + VC4_LINEAR_PHASE_KERNEL(0, -2, -6, -8, -10, -8, -3, 2, 18, + 50, 82, 119, 155, 187, 213, 227); ++static const u32 nearest_neighbour_kernel[] = ++ VC4_LINEAR_PHASE_KERNEL(0, 0, 0, 0, 0, 0, 0, 0, ++ 1, 1, 1, 1, 255, 255, 255, 255); + + static int vc4_hvs_upload_linear_kernel(struct vc4_hvs *hvs, + struct drm_mm_node *space, +@@ -2255,14 +2258,19 @@ static int vc4_hvs_bind(struct device *d + if (ret) + return ret; + +- /* Upload filter kernels. We only have the one for now, so we +- * keep it around for the lifetime of the driver. ++ /* Upload filter kernels. We only have the two for now, so we ++ * keep them around for the lifetime of the driver. + */ + ret = vc4_hvs_upload_linear_kernel(hvs, + &hvs->mitchell_netravali_filter, + mitchell_netravali_1_3_1_3_kernel); + if (ret) + return ret; ++ ret = vc4_hvs_upload_linear_kernel(hvs, ++ &hvs->nearest_neighbour_filter, ++ nearest_neighbour_kernel); ++ if (ret) ++ return ret; + + ret = vc4_hvs_cob_init(hvs); + if (ret) +@@ -2288,6 +2296,8 @@ static void vc4_hvs_unbind(struct device + + if (drm_mm_node_allocated(&vc4->hvs->mitchell_netravali_filter)) + drm_mm_remove_node(&vc4->hvs->mitchell_netravali_filter); ++ if (drm_mm_node_allocated(&vc4->hvs->nearest_neighbour_filter)) ++ drm_mm_remove_node(&vc4->hvs->nearest_neighbour_filter); + + drm_mm_for_each_node_safe(node, next, &vc4->hvs->dlist_mm) + drm_mm_remove_node(node); +--- a/drivers/gpu/drm/vc4/vc4_plane.c ++++ b/drivers/gpu/drm/vc4/vc4_plane.c +@@ -582,7 +582,9 @@ static void vc4_write_tpz(struct vc4_pla + /* phase magnitude bits */ + #define PHASE_BITS 6 + +-static void vc4_write_ppf(struct vc4_plane_state *vc4_state, u32 src, u32 dst, u32 xy, int channel, int chroma_offset) ++static void vc4_write_ppf(struct vc4_plane_state *vc4_state, u32 src, u32 dst, ++ u32 xy, int channel, int chroma_offset, ++ bool no_interpolate) + { + struct vc4_dev *vc4 = to_vc4_dev(vc4_state->base.plane->dev); + u32 scale = src / dst; +@@ -621,6 +623,7 @@ static void vc4_write_ppf(struct vc4_pla + phase &= SCALER_PPF_IPHASE_MASK; + + vc4_dlist_write(vc4_state, ++ no_interpolate ? SCALER_PPF_NOINTERP : 0 | + SCALER_PPF_AGC | + VC4_SET_FIELD(scale, SCALER_PPF_SCALE) | + /* +@@ -815,15 +818,17 @@ static void vc4_write_scaling_parameters + /* Ch0 H-PPF Word 0: Scaling Parameters */ + if (vc4_state->x_scaling[channel] == VC4_SCALING_PPF) { + vc4_write_ppf(vc4_state, +- vc4_state->src_w[channel], vc4_state->crtc_w, vc4_state->src_x, channel, +- state->chroma_siting_h); ++ vc4_state->src_w[channel], vc4_state->crtc_w, vc4_state->src_x, ++ channel, state->chroma_siting_h, ++ state->scaling_filter == DRM_SCALING_FILTER_NEAREST_NEIGHBOR); + } + + /* Ch0 V-PPF Words 0-1: Scaling Parameters, Context */ + if (vc4_state->y_scaling[channel] == VC4_SCALING_PPF) { + vc4_write_ppf(vc4_state, +- vc4_state->src_h[channel], vc4_state->crtc_h, vc4_state->src_y, channel, +- state->chroma_siting_v); ++ vc4_state->src_h[channel], vc4_state->crtc_h, vc4_state->src_y, ++ channel, state->chroma_siting_v, ++ state->scaling_filter == DRM_SCALING_FILTER_NEAREST_NEIGHBOR); + vc4_dlist_write(vc4_state, 0xc0c0c0c0); + } + +@@ -1573,7 +1578,18 @@ static int vc4_plane_mode_set(struct drm + vc4_state->y_scaling[0] == VC4_SCALING_PPF || + vc4_state->x_scaling[1] == VC4_SCALING_PPF || + vc4_state->y_scaling[1] == VC4_SCALING_PPF) { +- u32 kernel = VC4_SET_FIELD(vc4->hvs->mitchell_netravali_filter.start, ++ struct drm_mm_node *filter; ++ ++ switch (state->scaling_filter) { ++ case DRM_SCALING_FILTER_DEFAULT: ++ default: ++ filter = &vc4->hvs->mitchell_netravali_filter; ++ break; ++ case DRM_SCALING_FILTER_NEAREST_NEIGHBOR: ++ filter = &vc4->hvs->nearest_neighbour_filter; ++ break; ++ } ++ u32 kernel = VC4_SET_FIELD(filter->start, + SCALER_PPF_KERNEL_OFFSET); + + /* HPPF plane 0 */ +@@ -1984,9 +2000,19 @@ static int vc6_plane_mode_set(struct drm + vc4_state->y_scaling[0] == VC4_SCALING_PPF || + vc4_state->x_scaling[1] == VC4_SCALING_PPF || + vc4_state->y_scaling[1] == VC4_SCALING_PPF) { +- u32 kernel = +- VC4_SET_FIELD(vc4->hvs->mitchell_netravali_filter.start, +- SCALER_PPF_KERNEL_OFFSET); ++ struct drm_mm_node *filter; ++ ++ switch (state->scaling_filter) { ++ case DRM_SCALING_FILTER_DEFAULT: ++ default: ++ filter = &vc4->hvs->mitchell_netravali_filter; ++ break; ++ case DRM_SCALING_FILTER_NEAREST_NEIGHBOR: ++ filter = &vc4->hvs->nearest_neighbour_filter; ++ break; ++ } ++ u32 kernel = VC4_SET_FIELD(filter->start, ++ SCALER_PPF_KERNEL_OFFSET); + + /* HPPF plane 0 */ + vc4_dlist_write(vc4_state, kernel); +@@ -2468,6 +2494,10 @@ struct drm_plane *vc4_plane_init(struct + DRM_COLOR_YCBCR_BT709, + DRM_COLOR_YCBCR_LIMITED_RANGE); + ++ drm_plane_create_scaling_filter_property(plane, ++ BIT(DRM_SCALING_FILTER_DEFAULT) | ++ BIT(DRM_SCALING_FILTER_NEAREST_NEIGHBOR)); ++ + drm_plane_create_chroma_siting_properties(plane, 0, 0); + + if (type == DRM_PLANE_TYPE_PRIMARY) diff --git a/target/linux/bcm27xx/patches-6.6/950-1258-drm-panel-waveshare-Remove-duplicated-sentinel-on-co.patch b/target/linux/bcm27xx/patches-6.6/950-1258-drm-panel-waveshare-Remove-duplicated-sentinel-on-co.patch new file mode 100644 index 00000000000..215cc3cf768 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1258-drm-panel-waveshare-Remove-duplicated-sentinel-on-co.patch @@ -0,0 +1,37 @@ +From 7a3d1c22ecbdac458883991beae0461137cbfc8a Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Thu, 12 Sep 2024 18:04:58 +0100 +Subject: [PATCH 1258/1350] drm: panel: waveshare: Remove duplicated sentinel + on compatible list + +Remove the duplicated sentinel that got added, otherwise we have +an extra blank compatible string match in the module, and that matches +everything. + +$ modinfo panel_waveshare_dsi +filename: /lib/modules/6.6.50-v8+/kernel/drivers/gpu/drm/panel/panel-waveshare-dsi.ko.xz +license: GPL +description: Waveshare DSI panel driver +author: Dave Stevenson +srcversion: E767180DABD8B00B45571AF +alias: of:N*T*C* +alias: of:N*T* +alias: of:N*T*Cwaveshare,8.8inch-panelC* +alias: of:N*T*Cwaveshare,8.8inch-panel + +Fixes: f955b7838f9c ("drivers:gpu:drm:panel: Added waveshare 5.0inch, 6.25inch, and 8.8inch dsi screen devices") +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/panel/panel-waveshare-dsi.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/gpu/drm/panel/panel-waveshare-dsi.c ++++ b/drivers/gpu/drm/panel/panel-waveshare-dsi.c +@@ -467,7 +467,6 @@ static const struct of_device_id ws_pane + .compatible = "waveshare,8.8inch-panel", + .data = &ws_panel_8_8_mode, + }, { +- }, { + /* sentinel */ + } + }; diff --git a/target/linux/bcm27xx/patches-6.6/950-1019-drivers-mmc-disable-write-caching-on-Samsung-2023-mo.patch b/target/linux/bcm27xx/patches-6.6/950-1260-drivers-mmc-disable-write-caching-on-Samsung-2023-mo.patch similarity index 92% rename from target/linux/bcm27xx/patches-6.6/950-1019-drivers-mmc-disable-write-caching-on-Samsung-2023-mo.patch rename to target/linux/bcm27xx/patches-6.6/950-1260-drivers-mmc-disable-write-caching-on-Samsung-2023-mo.patch index 73a6b708567..35607aacafb 100644 --- a/target/linux/bcm27xx/patches-6.6/950-1019-drivers-mmc-disable-write-caching-on-Samsung-2023-mo.patch +++ b/target/linux/bcm27xx/patches-6.6/950-1260-drivers-mmc-disable-write-caching-on-Samsung-2023-mo.patch @@ -1,7 +1,7 @@ -From 43730828eca754b4b527d79fc5a1d3ff50c50481 Mon Sep 17 00:00:00 2001 +From c9b61d1d83073761871c7acba332216494e6f0bb Mon Sep 17 00:00:00 2001 From: Jonathan Bell Date: Mon, 8 Apr 2024 16:09:52 +0100 -Subject: [PATCH 1019/1085] drivers: mmc: disable write-caching on Samsung 2023 +Subject: [PATCH 1260/1350] drivers: mmc: disable write-caching on Samsung 2023 model year SD cards Samsung EVO Plus, Pro Plus and Evo Ultimate cards of this era appear to diff --git a/target/linux/bcm27xx/patches-6.6/950-1261-mm-vmscan-Maintain-TLB-coherency-in-LRU-code.patch b/target/linux/bcm27xx/patches-6.6/950-1261-mm-vmscan-Maintain-TLB-coherency-in-LRU-code.patch new file mode 100644 index 00000000000..70ece97505c --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1261-mm-vmscan-Maintain-TLB-coherency-in-LRU-code.patch @@ -0,0 +1,27 @@ +From 536f2097dc397e4ebd0566e8f00219c02d7c8073 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Thu, 12 Sep 2024 10:06:50 +0100 +Subject: [PATCH 1261/1350] mm/vmscan: Maintain TLB coherency in LRU code + +As a workaround (and possibly a fix) for CPU spins observed on BCM2837, +use ptep_clear_flush_young instead of ptep_test_and_clear_young inside +lru_gen_look_around in order to expose PTE changes to the MMU. Note that +on architectures that don't require an explicit flush, +ptep_clear_flush_young just calls ptep_test_and_clear_young. + +Signed-off-by: Phil Elwell +--- + mm/vmscan.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -4716,7 +4716,7 @@ void lru_gen_look_around(struct page_vma + if (!folio) + continue; + +- if (!ptep_test_and_clear_young(vma, addr, pte + i)) ++ if (!ptep_clear_flush_young(vma, addr, pte + i)) + VM_WARN_ON_ONCE(true); + + young++; diff --git a/target/linux/bcm27xx/patches-6.6/950-1262-drm-panel-ili9881-Correct-symmetry-on-enable-disable.patch b/target/linux/bcm27xx/patches-6.6/950-1262-drm-panel-ili9881-Correct-symmetry-on-enable-disable.patch new file mode 100644 index 00000000000..d10eee3c0bd --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1262-drm-panel-ili9881-Correct-symmetry-on-enable-disable.patch @@ -0,0 +1,35 @@ +From c763cf351ea25b7fb31f2d388dab0838565d1b75 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 13 Sep 2024 14:44:08 +0100 +Subject: [PATCH 1262/1350] drm: panel: ili9881: Correct symmetry on + enable/disable return codes + +ili9881c_enable is always returning 0. + +ili9881c_disable was returning the error code from +mipi_dsi_dcs_set_display_off. +If non-zero, the drm_panel framework will leave the panel marked as +enabled, and not run the enable hook next time around. That isn't +helpful, particularly as we're expecting unprepare to disable +resets and regulators. + +Change ili9881c_disable to match enable in always returning 0. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/panel/panel-ilitek-ili9881c.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c ++++ b/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c +@@ -1745,7 +1745,9 @@ static int ili9881c_disable(struct drm_p + { + struct ili9881c *ctx = panel_to_ili9881c(panel); + +- return mipi_dsi_dcs_set_display_off(ctx->dsi); ++ mipi_dsi_dcs_set_display_off(ctx->dsi); ++ ++ return 0; + } + + static int ili9881c_unprepare(struct drm_panel *panel) diff --git a/target/linux/bcm27xx/patches-6.6/950-1263-dtoverlays-adds-the-definitions-for-the-HiFiBerry-8-.patch b/target/linux/bcm27xx/patches-6.6/950-1263-dtoverlays-adds-the-definitions-for-the-HiFiBerry-8-.patch new file mode 100644 index 00000000000..0dff678d934 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1263-dtoverlays-adds-the-definitions-for-the-HiFiBerry-8-.patch @@ -0,0 +1,113 @@ +From 77773aec03f65758c760ec5b43a79ad6edeb211b Mon Sep 17 00:00:00 2001 +From: j-schambacher +Date: Thu, 12 Sep 2024 16:44:12 +0200 +Subject: [PATCH 1263/1350] dtoverlays: adds the definitions for the HiFiBerry + 8-channel ADC + +Additions and changes for the 8 channel ADC card. This card uses only +HW-controlled devices which allows the uses of the 'dummy-dai'. +It will run only on a PI5 as it requires the designware I2S0 module. + +The necessary output lanes I2S0_DI[0..3] are claimed from within the +DT overlay. + +Signed-off-by: j-schambacher +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 6 +++ + .../dts/overlays/hifiberry-adc8x-overlay.dts | 50 +++++++++++++++++++ + arch/arm/boot/dts/overlays/overlay_map.dts | 4 ++ + 4 files changed, 61 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/hifiberry-adc8x-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -86,6 +86,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + hd44780-lcd.dtbo \ + hdmi-backlight-hwhack-gpio.dtbo \ + hifiberry-adc.dtbo \ ++ hifiberry-adc8x.dtbo \ + hifiberry-amp.dtbo \ + hifiberry-amp100.dtbo \ + hifiberry-amp3.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1778,6 +1778,12 @@ Params: leds_off If set t + is switched off at all times. + + ++Name: hifiberry-adc8x ++Info: Configures the HifiBerry ADC8X audio card (only on Pi5) ++Load: dtoverlay=hifiberry-adc8x ++Params: ++ ++ + Name: hifiberry-amp + Info: Configures the HifiBerry Amp and Amp+ audio cards + Load: dtoverlay=hifiberry-amp +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/hifiberry-adc8x-overlay.dts +@@ -0,0 +1,50 @@ ++// Definitions for HiFiBerry ADC8x ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2712"; ++ ++ fragment@0 { ++ target = <&gpio>; ++ __overlay__ { ++ rp1_i2s0_adc8x: rp1_i2s0_adc8x { ++ function = "i2s0"; ++ pins = "gpio18", "gpio19", "gpio20", ++ "gpio22", "gpio24", "gpio26"; ++ bias-disable; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2s_clk_producer>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&rp1_i2s0_adc8x>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target-path = "/"; ++ __overlay__ { ++ dummy-codec { ++ #sound-dai-cells = <0>; ++ compatible = "snd-soc-dummy"; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@3 { ++ target = <&sound>; ++ __overlay__ { ++ compatible = "hifiberry,hifiberry-adc8x"; ++ i2s-controller = <&i2s_clk_producer>; ++ status = "okay"; ++ }; ++ }; ++ ++}; +--- a/arch/arm/boot/dts/overlays/overlay_map.dts ++++ b/arch/arm/boot/dts/overlays/overlay_map.dts +@@ -48,6 +48,10 @@ + bcm2712; + }; + ++ hifiberry-adc8x { ++ bcm2712; ++ }; ++ + hifiberry-dac8x { + bcm2712; + }; diff --git a/target/linux/bcm27xx/patches-6.6/950-1264-ASoC-add-HiFiBerry-ADC8x-8-channel-ADC-to-simple-car.patch b/target/linux/bcm27xx/patches-6.6/950-1264-ASoC-add-HiFiBerry-ADC8x-8-channel-ADC-to-simple-car.patch new file mode 100644 index 00000000000..87d523e2a6b --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1264-ASoC-add-HiFiBerry-ADC8x-8-channel-ADC-to-simple-car.patch @@ -0,0 +1,88 @@ +From 4d2eaa194d77588fa42567ba174c3c14c5798027 Mon Sep 17 00:00:00 2001 +From: j-schambacher +Date: Thu, 12 Sep 2024 17:42:13 +0200 +Subject: [PATCH 1264/1350] ASoC: add HiFiBerry ADC8x 8-channel ADC to + simple-card-driver + +Definitions for the 8 channel ADC card. The card uses only +HW-controlled devices which allows the uses of the 'dummy-dai'. +It will run only on a PI5 as it requires the designware I2S0 module. + +The necessary output lanes I2S0_DI[0..3] are claimed from within the +DT overlay. + +Signed-off-by: j-schambacher +--- + sound/soc/bcm/Kconfig | 7 ++++++ + sound/soc/bcm/rpi-simple-soundcard.c | 37 ++++++++++++++++++++++++++++ + 2 files changed, 44 insertions(+) + +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -47,6 +47,13 @@ config SND_BCM2708_SOC_HIFIBERRY_ADC + Say Y or M if you want to add support for HifiBerry ADC. + Use this module for HiFiBerry's ADC-only sound cards + ++config SND_BCM2708_SOC_HIFIBERRY_ADC8X ++ tristate "Support for HifiBerry ADC8X" ++ select SND_RPI_SIMPLE_SOUNDCARD ++ help ++ Say Y or M if you want to add support for HifiBerry ADC8X. ++ Note: ADC8X only works on PI5 ++ + config SND_BCM2708_SOC_HIFIBERRY_DAC + tristate "Support for HifiBerry DAC and DAC8X" + select SND_SOC_PCM5102A +--- a/sound/soc/bcm/rpi-simple-soundcard.c ++++ b/sound/soc/bcm/rpi-simple-soundcard.c +@@ -254,6 +254,41 @@ static struct snd_rpi_simple_drvdata drv + .dai = snd_hifiberrydacplusdsp_soundcard_dai, + }; + ++SND_SOC_DAILINK_DEFS(hifiberry_adc, ++ DAILINK_COMP_ARRAY(COMP_EMPTY()), ++ DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")), ++ DAILINK_COMP_ARRAY(COMP_EMPTY())); ++ ++static int hifiberry_adc8x_init(struct snd_soc_pcm_runtime *rtd) ++{ ++ struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); ++ ++ /* set limits of 8 channels and 192ksps sample rate ++ */ ++ codec_dai->driver->capture.channels_max = 8; ++ codec_dai->driver->capture.rates = SNDRV_PCM_RATE_8000_192000; ++ ++ return 0; ++} ++ ++static struct snd_soc_dai_link snd_hifiberry_adc8x_dai[] = { ++ { ++ .name = "HifiBerry ADC8x", ++ .stream_name = "HifiBerry ADC8x HiFi", ++ .dai_fmt = SND_SOC_DAIFMT_I2S | ++ SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBS_CFS, ++ .init = hifiberry_adc8x_init, ++ SND_SOC_DAILINK_REG(hifiberry_adc), ++ }, ++}; ++ ++static struct snd_rpi_simple_drvdata drvdata_hifiberry_adc8x = { ++ .card_name = "snd_rpi_hifiberry_adc8x", ++ .dai = snd_hifiberry_adc8x_dai, ++ .fixed_bclk_ratio = 64, ++}; ++ + SND_SOC_DAILINK_DEFS(hifiberry_amp, + DAILINK_COMP_ARRAY(COMP_EMPTY()), + DAILINK_COMP_ARRAY(COMP_CODEC("tas5713.1-001b", "tas5713-hifi")), +@@ -445,6 +480,8 @@ static const struct of_device_id snd_rpi + .data = (void *) &drvdata_googlevoicehat }, + { .compatible = "hifiberrydacplusdsp,hifiberrydacplusdsp-soundcard", + .data = (void *) &drvdata_hifiberrydacplusdsp }, ++ { .compatible = "hifiberry,hifiberry-adc8x", ++ .data = (void *) &drvdata_hifiberry_adc8x }, + { .compatible = "hifiberry,hifiberry-amp", + .data = (void *) &drvdata_hifiberry_amp }, + { .compatible = "hifiberry,hifiberry-amp3", diff --git a/target/linux/bcm27xx/patches-6.6/950-1265-vc04_services-codec-Allocate-the-max-number-of-buffe.patch b/target/linux/bcm27xx/patches-6.6/950-1265-vc04_services-codec-Allocate-the-max-number-of-buffe.patch new file mode 100644 index 00000000000..aa4c7594af0 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1265-vc04_services-codec-Allocate-the-max-number-of-buffe.patch @@ -0,0 +1,35 @@ +From 8c9ca647449ba9df7e3b300c480242f9b5bdd867 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 10 Sep 2024 16:58:56 +0100 +Subject: [PATCH 1265/1350] vc04_services: codec: Allocate the max number of + buffers on the VPU + +The VPU's API can't match the use of VIDIOC_CREATE_BUFS to add buffers +to the internal pool whilst a port is enabled, therefore allocate +the maximum number of buffers possible in V4L2 to avoid the issue. +As these are only buffer headers, the overhead is relatively small. + +Signed-off-by: Dave Stevenson +--- + .../vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c ++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c +@@ -2871,8 +2871,14 @@ static int bcm2835_codec_queue_setup(str + + if (*nbuffers < port->minimum_buffer.num) + *nbuffers = port->minimum_buffer.num; +- /* Add one buffer to take an EOS */ +- port->current_buffer.num = *nbuffers + 1; ++ ++ /* ++ * The VPU uses this number to allocate a pool of headers at port_enable. ++ * We can't increase it later, so use of CREATE_BUFS is going to result ++ * in bad things happening. Adopt worst-case allocation, and add one ++ * buffer to take an EOS ++ */ ++ port->current_buffer.num = VB2_MAX_FRAME + 1; + + return 0; + } diff --git a/target/linux/bcm27xx/patches-6.6/950-1266-drm-vc4-Fix-interpolate-bit-for-nearest-neighbour-fi.patch b/target/linux/bcm27xx/patches-6.6/950-1266-drm-vc4-Fix-interpolate-bit-for-nearest-neighbour-fi.patch new file mode 100644 index 00000000000..7fd30b65502 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1266-drm-vc4-Fix-interpolate-bit-for-nearest-neighbour-fi.patch @@ -0,0 +1,26 @@ +From c1321370c9af9681e0604c4d3363cf362fb48598 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 16 Sep 2024 15:56:51 +0100 +Subject: [PATCH 1266/1350] drm: vc4: Fix interpolate bit for nearest neighbour + filter + +Operator precedence resulted in the wrong value being written +for nearest neighbour mode. Correct it. + +Fixes: d6a3a3f10601 ("drm/vc4: Add support for per plane scaling filter selection") +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_plane.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/gpu/drm/vc4/vc4_plane.c ++++ b/drivers/gpu/drm/vc4/vc4_plane.c +@@ -623,7 +623,7 @@ static void vc4_write_ppf(struct vc4_pla + phase &= SCALER_PPF_IPHASE_MASK; + + vc4_dlist_write(vc4_state, +- no_interpolate ? SCALER_PPF_NOINTERP : 0 | ++ (no_interpolate ? SCALER_PPF_NOINTERP : 0) | + SCALER_PPF_AGC | + VC4_SET_FIELD(scale, SCALER_PPF_SCALE) | + /* diff --git a/target/linux/bcm27xx/patches-6.6/950-1267-dts-rp1-Disable-DMA-usage-for-UART0.patch b/target/linux/bcm27xx/patches-6.6/950-1267-dts-rp1-Disable-DMA-usage-for-UART0.patch new file mode 100644 index 00000000000..c809c4f10b6 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1267-dts-rp1-Disable-DMA-usage-for-UART0.patch @@ -0,0 +1,34 @@ +From cc63d552b9aab92fb581dfb08267d5af697f477b Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 18 Sep 2024 16:45:24 +0100 +Subject: [PATCH 1267/1350] dts: rp1: Disable DMA usage for UART0 + +Some recent DMA changes have led to data loss in UART0 on Pi 5. It also +seems that even prior to these changes there was a problem with aborted +transfers. + +As this is the only RP1 UART configured for DMA, it is better to remove +the DMA usage until it is shown to be reliable. + +Link: https://github.com/raspberrypi/linux/issues/6365 + +Signed-off-by: Phil Elwell +--- + arch/arm64/boot/dts/broadcom/rp1.dtsi | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/arch/arm64/boot/dts/broadcom/rp1.dtsi ++++ b/arch/arm64/boot/dts/broadcom/rp1.dtsi +@@ -55,9 +55,9 @@ + interrupts = ; + clocks = <&rp1_clocks RP1_CLK_UART &rp1_clocks RP1_PLL_SYS_PRI_PH>; + clock-names = "uartclk", "apb_pclk"; +- dmas = <&rp1_dma RP1_DMA_UART0_TX>, +- <&rp1_dma RP1_DMA_UART0_RX>; +- dma-names = "tx", "rx"; ++ // dmas = <&rp1_dma RP1_DMA_UART0_TX>, ++ // <&rp1_dma RP1_DMA_UART0_RX>; ++ // dma-names = "tx", "rx"; + pinctrl-names = "default"; + arm,primecell-periphid = <0x00541011>; + uart-has-rtscts; diff --git a/target/linux/bcm27xx/patches-6.6/950-1269-drivers-media-imx500-Fixes-for-vblank-control.patch b/target/linux/bcm27xx/patches-6.6/950-1269-drivers-media-imx500-Fixes-for-vblank-control.patch new file mode 100644 index 00000000000..9b47eedca51 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1269-drivers-media-imx500-Fixes-for-vblank-control.patch @@ -0,0 +1,50 @@ +From f6c0447dfb915538a0d5fa966fc26ca022cf49c8 Mon Sep 17 00:00:00 2001 +From: Naushir Patuck +Date: Fri, 20 Sep 2024 08:25:58 +0100 +Subject: [PATCH 1269/1350] drivers: media: imx500: Fixes for vblank control + +Reduce the default/max framerate of the 2x2 binned mode to 30fps. +The current limit of 50fps can cause the sensor to produce corrupt +frames and cause missing framing events. + +Also fixup the vblank control min/max/default/step paramters when +setting up. + +Signed-off-by: Naushir Patuck +--- + drivers/media/i2c/imx500.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/media/i2c/imx500.c ++++ b/drivers/media/i2c/imx500.c +@@ -47,7 +47,7 @@ + /* V_TIMING internal */ + #define IMX500_REG_FRAME_LENGTH CCI_REG16(0x0340) + #define IMX500_FRAME_LENGTH_MAX 0xffdc +-#define IMX500_VBLANK_MIN 4 ++#define IMX500_VBLANK_MIN 1117 + + /* H_TIMING internal */ + #define IMX500_REG_LINE_LENGTH CCI_REG16(0x0342) +@@ -922,7 +922,7 @@ static const struct imx500_mode imx500_s + .width = 4056, + .height = 3040, + }, +- .framerate_default = 40, ++ .framerate_default = 30, + .reg_list = { + .num_of_regs = ARRAY_SIZE(mode_2028x1520_regs), + .regs = mode_2028x1520_regs, +@@ -1771,10 +1771,10 @@ static void imx500_set_framing_limits(st + + /* Update limits and set FPS to default */ + __v4l2_ctrl_modify_range( +- imx500->vblank, 1, ++ imx500->vblank, IMX500_VBLANK_MIN, + ((1 << IMX500_LONG_EXP_SHIFT_MAX) * IMX500_FRAME_LENGTH_MAX) - + mode->height, +- IMX500_VBLANK_MIN, frm_length_default - mode->height); ++ 1, frm_length_default - mode->height); + + /* Setting this will adjust the exposure limits as well. */ + __v4l2_ctrl_s_ctrl(imx500->vblank, frm_length_default - mode->height); diff --git a/target/linux/bcm27xx/patches-6.6/950-1270-drm-bridge-Document-bridge-init-order-with-pre_enabl.patch b/target/linux/bcm27xx/patches-6.6/950-1270-drm-bridge-Document-bridge-init-order-with-pre_enabl.patch new file mode 100644 index 00000000000..14f9dd8d847 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1270-drm-bridge-Document-bridge-init-order-with-pre_enabl.patch @@ -0,0 +1,56 @@ +From d62184f6b06627b4fe922b08132e38c181d389a0 Mon Sep 17 00:00:00 2001 +From: Jagan Teki +Date: Tue, 28 Mar 2023 22:37:52 +0530 +Subject: [PATCH 1270/1350] drm/bridge: Document bridge init order with + pre_enable_prev_first +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Upstream commit 113cc3ad8566e06d6c8ef4fc0075a938dedefab5 + +In order to satisfy the MIPI DSI initialization sequence the bridge +init order has been altered with the help of pre_enable_prev_first +in pre_enable and post_disable bridge operations. + +Document the affected bridge init order with an example on the +bridge operations helpers. + +Signed-off-by: Jagan Teki +Reviewed-by: Dave Stevenson +Signed-off-by: Robert Foss +Link: https://patchwork.freedesktop.org/patch/msgid/20230328170752.1102347-2-jagan@amarulasolutions.com +--- + drivers/gpu/drm/drm_bridge.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +--- a/drivers/gpu/drm/drm_bridge.c ++++ b/drivers/gpu/drm/drm_bridge.c +@@ -657,6 +657,13 @@ static void drm_atomic_bridge_call_post_ + * bridge will be called before the previous one to reverse the @pre_enable + * calling direction. + * ++ * Example: ++ * Bridge A ---> Bridge B ---> Bridge C ---> Bridge D ---> Bridge E ++ * ++ * With pre_enable_prev_first flag enable in Bridge B, D, E then the resulting ++ * @post_disable order would be, ++ * Bridge B, Bridge A, Bridge E, Bridge D, Bridge C. ++ * + * Note: the bridge passed should be the one closest to the encoder + */ + void drm_atomic_bridge_chain_post_disable(struct drm_bridge *bridge, +@@ -753,6 +760,13 @@ static void drm_atomic_bridge_call_pre_e + * If a bridge sets @pre_enable_prev_first, then the pre_enable for the + * prev bridge will be called before pre_enable of this bridge. + * ++ * Example: ++ * Bridge A ---> Bridge B ---> Bridge C ---> Bridge D ---> Bridge E ++ * ++ * With pre_enable_prev_first flag enable in Bridge B, D, E then the resulting ++ * @pre_enable order would be, ++ * Bridge C, Bridge D, Bridge E, Bridge A, Bridge B. ++ * + * Note: the bridge passed should be the one closest to the encoder + */ + void drm_atomic_bridge_chain_pre_enable(struct drm_bridge *bridge, diff --git a/target/linux/bcm27xx/patches-6.6/950-1271-drm-vc4-dsi-Don-t-reset-the-host-until-post_disable.patch b/target/linux/bcm27xx/patches-6.6/950-1271-drm-vc4-dsi-Don-t-reset-the-host-until-post_disable.patch new file mode 100644 index 00000000000..11094eb801c --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1271-drm-vc4-dsi-Don-t-reset-the-host-until-post_disable.patch @@ -0,0 +1,50 @@ +From ef34d0100e0f2f137ad0e6af333aad4e0d5c3319 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Thu, 2 May 2024 12:03:58 +0100 +Subject: [PATCH 1271/1350] drm/vc4: dsi: Don't reset the host until + post_disable + +Some DSI peripheral drivers wish to send commands in the +post_disable or panel unprepare callback. These are called +after the DSI host's disable call, but before the host's +post_disable if pre_enable_prev_first is set. + +Don't reset the block until post_disable to allow these +commands to be sent. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_dsi.c | 15 +++++++-------- + 1 file changed, 7 insertions(+), 8 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_dsi.c ++++ b/drivers/gpu/drm/vc4/vc4_dsi.c +@@ -818,6 +818,13 @@ static void vc4_dsi_bridge_disable(struc + disp0_ctrl = DSI_PORT_READ(DISP0_CTRL); + disp0_ctrl &= ~DSI_DISP0_ENABLE; + DSI_PORT_WRITE(DISP0_CTRL, disp0_ctrl); ++} ++ ++static void vc4_dsi_bridge_post_disable(struct drm_bridge *bridge, ++ struct drm_bridge_state *state) ++{ ++ struct vc4_dsi *dsi = bridge_to_vc4_dsi(bridge); ++ struct device *dev = &dsi->pdev->dev; + + /* Reset the DSI and all its fifos. */ + DSI_PORT_WRITE(CTRL, DSI_CTRL_SOFT_RESET_CFG | +@@ -828,14 +835,6 @@ static void vc4_dsi_bridge_disable(struc + DSI_PORT_BIT(PHY_AFEC0_PD) | + DSI_PORT_BIT(AFEC0_PD_ALL_LANES)); + +-} +- +-static void vc4_dsi_bridge_post_disable(struct drm_bridge *bridge, +- struct drm_bridge_state *state) +-{ +- struct vc4_dsi *dsi = bridge_to_vc4_dsi(bridge); +- struct device *dev = &dsi->pdev->dev; +- + clk_disable_unprepare(dsi->pll_phy_clock); + clk_disable_unprepare(dsi->escape_clock); + clk_disable_unprepare(dsi->pixel_clock); diff --git a/target/linux/bcm27xx/patches-6.6/950-1272-drm-vc4-dsi-enable-video-and-then-retry-failed-trans.patch b/target/linux/bcm27xx/patches-6.6/950-1272-drm-vc4-dsi-enable-video-and-then-retry-failed-trans.patch new file mode 100644 index 00000000000..e39e3b58655 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1272-drm-vc4-dsi-enable-video-and-then-retry-failed-trans.patch @@ -0,0 +1,111 @@ +From 6da70162dd1e729c04e2dc25472b39390868af79 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 20 Sep 2024 12:05:18 +0100 +Subject: [PATCH 1272/1350] drm: vc4: dsi: enable video and then retry failed + transfers + +The DSI block appears to be able to come up stuck in a condition where +it leaves the lanes in HS mode or just jabbering. This stops LP +transfers from completing as there is no LP time available. This is +signalled via the LP1 contention error. + +Enabling video briefly clears that condition, so if we detect the +error condition, enable video mode and then retry. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_dsi.c | 54 +++++++++++++++++++++++++++++------ + 1 file changed, 46 insertions(+), 8 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_dsi.c ++++ b/drivers/gpu/drm/vc4/vc4_dsi.c +@@ -286,6 +286,8 @@ + DSI1_INT_PR_TO) + + #define DSI0_STAT 0x2c ++# define DSI0_STAT_ERR_CONT_LP1 BIT(6) ++# define DSI0_STAT_ERR_CONT_LP0 BIT(5) + #define DSI0_HSTX_TO_CNT 0x30 + #define DSI0_LPRX_TO_CNT 0x34 + #define DSI0_TA_TO_CNT 0x38 +@@ -1203,10 +1205,9 @@ static int vc4_dsi_bridge_attach(struct + &dsi->bridge, flags); + } + +-static ssize_t vc4_dsi_host_transfer(struct mipi_dsi_host *host, +- const struct mipi_dsi_msg *msg) ++static ssize_t vc4_dsi_transfer(struct vc4_dsi *dsi, ++ const struct mipi_dsi_msg *msg, bool log_error) + { +- struct vc4_dsi *dsi = host_to_dsi(host); + struct mipi_dsi_packet packet; + u32 pkth = 0, pktc = 0; + int i, ret; +@@ -1315,10 +1316,12 @@ static ssize_t vc4_dsi_host_transfer(str + DSI_PORT_WRITE(TXPKT1C, pktc); + + if (!wait_for_completion_timeout(&dsi->xfer_completion, +- msecs_to_jiffies(1000))) { +- dev_err(&dsi->pdev->dev, "transfer interrupt wait timeout"); +- dev_err(&dsi->pdev->dev, "instat: 0x%08x\n", +- DSI_PORT_READ(INT_STAT)); ++ msecs_to_jiffies(500))) { ++ if (log_error) { ++ dev_err(&dsi->pdev->dev, "transfer interrupt wait timeout"); ++ dev_err(&dsi->pdev->dev, "instat: 0x%08x, stat: 0x%08x\n", ++ DSI_PORT_READ(INT_STAT), DSI_PORT_READ(INT_STAT)); ++ } + ret = -ETIMEDOUT; + } else { + ret = dsi->xfer_result; +@@ -1361,7 +1364,8 @@ static ssize_t vc4_dsi_host_transfer(str + return ret; + + reset_fifo_and_return: +- DRM_ERROR("DSI transfer failed, resetting: %d\n", ret); ++ if (log_error) ++ DRM_ERROR("DSI transfer failed, resetting: %d\n", ret); + + DSI_PORT_WRITE(TXPKT1C, DSI_PORT_READ(TXPKT1C) & ~DSI_TXPKT1C_CMD_EN); + udelay(1); +@@ -1374,6 +1378,40 @@ reset_fifo_and_return: + return ret; + } + ++static ssize_t vc4_dsi_host_transfer(struct mipi_dsi_host *host, ++ const struct mipi_dsi_msg *msg) ++{ ++ struct vc4_dsi *dsi = host_to_dsi(host); ++ u32 stat, disp0_ctrl; ++ int ret; ++ ++ ret = vc4_dsi_transfer(dsi, msg, false); ++ ++ if (ret == -ETIMEDOUT) { ++ stat = DSI_PORT_READ(STAT); ++ disp0_ctrl = DSI_PORT_READ(DISP0_CTRL); ++ ++ DSI_PORT_WRITE(STAT, DSI_PORT_BIT(STAT_ERR_CONT_LP1)); ++ if (!(disp0_ctrl & DSI_DISP0_ENABLE)) { ++ /* If video mode not enabled, then try recovering by ++ * enabling it briefly to clear FIFOs and the state. ++ */ ++ disp0_ctrl |= DSI_DISP0_ENABLE; ++ DSI_PORT_WRITE(DISP0_CTRL, disp0_ctrl); ++ msleep(30); ++ disp0_ctrl &= ~DSI_DISP0_ENABLE; ++ DSI_PORT_WRITE(DISP0_CTRL, disp0_ctrl); ++ msleep(30); ++ ++ ret = vc4_dsi_transfer(dsi, msg, true); ++ } else { ++ DRM_ERROR("DSI transfer failed whilst in HS mode stat: 0x%08x\n", ++ stat); ++ } ++ } ++ return ret; ++} ++ + static const struct component_ops vc4_dsi_ops; + static int vc4_dsi_host_attach(struct mipi_dsi_host *host, + struct mipi_dsi_device *device) diff --git a/target/linux/bcm27xx/patches-6.6/950-1273-drm-panel-ili9881-Add-option-to-reconfigure-setup-co.patch b/target/linux/bcm27xx/patches-6.6/950-1273-drm-panel-ili9881-Add-option-to-reconfigure-setup-co.patch new file mode 100644 index 00000000000..16329253b94 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1273-drm-panel-ili9881-Add-option-to-reconfigure-setup-co.patch @@ -0,0 +1,102 @@ +From d644270369cc6bf39012cce735dde6b86ad01424 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Wed, 18 Sep 2024 16:09:28 +0100 +Subject: [PATCH 1273/1350] drm: panel: ili9881: Add option to reconfigure + setup commands + +The driver is typically asking for LP commands, but then tries +to send set_display_[on|off] from enable/disable when the host +will be in HS mode. +It also sends shutdown commands just before it asserts reset and +disables the regulator, which is rather redundant. + +Add an option to configure these two choices from the panel_desc. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/panel/panel-ilitek-ili9881c.c | 32 ++++++++++++++++--- + 1 file changed, 28 insertions(+), 4 deletions(-) + +--- a/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c ++++ b/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c +@@ -40,12 +40,19 @@ struct ili9881c_instr { + } arg; + }; + ++enum ili9881_desc_flags { ++ ILI9881_FLAGS_NO_SHUTDOWN_CMDS = BIT(0), ++ ILI9881_FLAGS_PANEL_ON_IN_PREPARE = BIT(1), ++ ILI9881_FLAGS_MAX = BIT(31), ++}; ++ + struct ili9881c_desc { + const struct ili9881c_instr *init; + const size_t init_length; + const struct drm_display_mode *mode; + const unsigned long mode_flags; + unsigned int lanes; ++ enum ili9881_desc_flags flags; + }; + + struct ili9881c { +@@ -1727,6 +1734,12 @@ static int ili9881c_prepare(struct drm_p + if (ret) + return ret; + ++ if (ctx->desc->flags & ILI9881_FLAGS_PANEL_ON_IN_PREPARE) { ++ msleep(120); ++ ++ ret = mipi_dsi_dcs_set_display_on(ctx->dsi); ++ } ++ + return 0; + } + +@@ -1734,9 +1747,11 @@ static int ili9881c_enable(struct drm_pa + { + struct ili9881c *ctx = panel_to_ili9881c(panel); + +- msleep(120); ++ if (!(ctx->desc->flags & ILI9881_FLAGS_PANEL_ON_IN_PREPARE)) { ++ msleep(120); + +- mipi_dsi_dcs_set_display_on(ctx->dsi); ++ mipi_dsi_dcs_set_display_on(ctx->dsi); ++ } + + return 0; + } +@@ -1745,7 +1760,8 @@ static int ili9881c_disable(struct drm_p + { + struct ili9881c *ctx = panel_to_ili9881c(panel); + +- mipi_dsi_dcs_set_display_off(ctx->dsi); ++ if (!(ctx->desc->flags & ILI9881_FLAGS_PANEL_ON_IN_PREPARE)) ++ mipi_dsi_dcs_set_display_off(ctx->dsi); + + return 0; + } +@@ -1754,7 +1770,13 @@ static int ili9881c_unprepare(struct drm + { + struct ili9881c *ctx = panel_to_ili9881c(panel); + +- mipi_dsi_dcs_enter_sleep_mode(ctx->dsi); ++ if (!(ctx->desc->flags & ILI9881_FLAGS_NO_SHUTDOWN_CMDS)) { ++ if (ctx->desc->flags & ILI9881_FLAGS_PANEL_ON_IN_PREPARE) ++ mipi_dsi_dcs_set_display_off(ctx->dsi); ++ ++ mipi_dsi_dcs_enter_sleep_mode(ctx->dsi); ++ } ++ + regulator_disable(ctx->power); + gpiod_set_value_cansleep(ctx->reset, 1); + +@@ -2066,6 +2088,8 @@ static const struct ili9881c_desc rpi_7i + .mode = &rpi_7inch_default_mode, + .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_LPM, + .lanes = 2, ++ .flags = ILI9881_FLAGS_NO_SHUTDOWN_CMDS | ++ ILI9881_FLAGS_PANEL_ON_IN_PREPARE, + }; + + static const struct of_device_id ili9881c_of_match[] = { diff --git a/target/linux/bcm27xx/patches-6.6/950-1274-regulator-rpi-panel-Remove-the-ID-read.patch b/target/linux/bcm27xx/patches-6.6/950-1274-regulator-rpi-panel-Remove-the-ID-read.patch new file mode 100644 index 00000000000..8336b7ae1ae --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1274-regulator-rpi-panel-Remove-the-ID-read.patch @@ -0,0 +1,90 @@ +From b510e5cbbf8b8e2da3198cf931452290629876b7 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 20 Sep 2024 18:32:11 +0100 +Subject: [PATCH 1274/1350] regulator/rpi-panel: Remove the ID read + +Reading from the Atmel has always been troublesome due to +clock stretching, and the driver does nothing with it anyway. + +Remove the read and assume that if the overlay has been +configured (most likely through the firmware autodetection) +that the hardware is present. + +Signed-off-by: Dave Stevenson +--- + .../regulator/rpi-panel-attiny-regulator.c | 50 ------------------- + 1 file changed, 50 deletions(-) + +--- a/drivers/regulator/rpi-panel-attiny-regulator.c ++++ b/drivers/regulator/rpi-panel-attiny-regulator.c +@@ -229,39 +229,6 @@ static void attiny_gpio_set(struct gpio_ + mutex_unlock(&state->lock); + } + +-static int attiny_i2c_read(struct i2c_client *client, u8 reg, unsigned int *buf) +-{ +- struct i2c_msg msgs[1]; +- u8 addr_buf[1] = { reg }; +- u8 data_buf[1] = { 0, }; +- int ret; +- +- /* Write register address */ +- msgs[0].addr = client->addr; +- msgs[0].flags = 0; +- msgs[0].len = ARRAY_SIZE(addr_buf); +- msgs[0].buf = addr_buf; +- +- ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); +- if (ret != ARRAY_SIZE(msgs)) +- return -EIO; +- +- usleep_range(5000, 10000); +- +- /* Read data from register */ +- msgs[0].addr = client->addr; +- msgs[0].flags = I2C_M_RD; +- msgs[0].len = 1; +- msgs[0].buf = data_buf; +- +- ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); +- if (ret != ARRAY_SIZE(msgs)) +- return -EIO; +- +- *buf = data_buf[0]; +- return 0; +-} +- + /* + * I2C driver interface functions + */ +@@ -273,7 +240,6 @@ static int attiny_i2c_probe(struct i2c_c + struct regulator_dev *rdev; + struct attiny_lcd *state; + struct regmap *regmap; +- unsigned int data; + int ret; + + state = devm_kzalloc(&i2c->dev, sizeof(*state), GFP_KERNEL); +@@ -291,22 +257,6 @@ static int attiny_i2c_probe(struct i2c_c + goto error; + } + +- ret = attiny_i2c_read(i2c, REG_ID, &data); +- if (ret < 0) { +- dev_err(&i2c->dev, "Failed to read REG_ID reg: %d\n", ret); +- goto error; +- } +- +- switch (data) { +- case 0xde: /* ver 1 */ +- case 0xc3: /* ver 2 */ +- break; +- default: +- dev_err(&i2c->dev, "Unknown Atmel firmware revision: 0x%02x\n", data); +- ret = -ENODEV; +- goto error; +- } +- + regmap_write(regmap, REG_POWERON, 0); + msleep(30); + regmap_write(regmap, REG_PWM, 0); diff --git a/target/linux/bcm27xx/patches-6.6/950-1275-drivers-mfd-sensehat-Add-Raspberry-Pi-Sense-HAT-to-s.patch b/target/linux/bcm27xx/patches-6.6/950-1275-drivers-mfd-sensehat-Add-Raspberry-Pi-Sense-HAT-to-s.patch new file mode 100644 index 00000000000..f89dfa8ffd4 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1275-drivers-mfd-sensehat-Add-Raspberry-Pi-Sense-HAT-to-s.patch @@ -0,0 +1,29 @@ +From 2f9fad762e8ed78aa4220d582b4d1856808f4a7a Mon Sep 17 00:00:00 2001 +From: Charles Mirabile +Date: Tue, 19 Apr 2022 16:51:53 -0400 +Subject: [PATCH 1275/1350] drivers/mfd: sensehat: Add Raspberry Pi Sense HAT + to simple_mfd_i2c + +This patch adds the compatible string for the Sense HAT device to +the list of compatible strings in the simple_mfd_i2c driver so that +it can match against the device and load its children and their drivers + +Co-developed-by: Mwesigwa Guma +Signed-off-by: Mwesigwa Guma +Co-developed-by: Joel Savitz +Signed-off-by: Joel Savitz +Signed-off-by: Charles Mirabile +--- + drivers/mfd/simple-mfd-i2c.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/mfd/simple-mfd-i2c.c ++++ b/drivers/mfd/simple-mfd-i2c.c +@@ -98,6 +98,7 @@ static const struct of_device_id simple_ + { .compatible = "maxim,max5970", .data = &maxim_max5970}, + { .compatible = "maxim,max5978", .data = &maxim_max5970}, + { .compatible = "raspberrypi,poe-core", &rpi_poe_core }, ++ { .compatible = "raspberrypi,sensehat" }, + {} + }; + MODULE_DEVICE_TABLE(of, simple_mfd_i2c_of_match); diff --git a/target/linux/bcm27xx/patches-6.6/950-1281-dtoverlays-Correct-pinctrl-assignment-on-mcp23017.patch b/target/linux/bcm27xx/patches-6.6/950-1281-dtoverlays-Correct-pinctrl-assignment-on-mcp23017.patch new file mode 100644 index 00000000000..ce0dd744a12 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1281-dtoverlays-Correct-pinctrl-assignment-on-mcp23017.patch @@ -0,0 +1,24 @@ +From 78518a36d7c87bafdbb06478e6b54be5df4b355b Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 23 Sep 2024 17:49:00 +0100 +Subject: [PATCH 1281/1350] dtoverlays: Correct pinctrl assignment on mcp23017 + +The pinctrl definition used "pinctrl-name" which is missing +an "s" from the end. + +Signed-off-by: Dave Stevenson +--- + arch/arm/boot/dts/overlays/mcp23017-overlay.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm/boot/dts/overlays/mcp23017-overlay.dts ++++ b/arch/arm/boot/dts/overlays/mcp23017-overlay.dts +@@ -34,7 +34,7 @@ + target = <&mcp23017>; + mcp23017_irq: __overlay__ { + #interrupt-cells=<2>; +- pinctrl-name = "default"; ++ pinctrl-names = "default"; + pinctrl-0 = <&mcp23017_pins>; + interrupt-parent = <&gpio>; + interrupts = <4 2>; diff --git a/target/linux/bcm27xx/patches-6.6/950-1282-tty-serial-pl011-Also-unregister-pl011_axi_platform_.patch b/target/linux/bcm27xx/patches-6.6/950-1282-tty-serial-pl011-Also-unregister-pl011_axi_platform_.patch new file mode 100644 index 00000000000..3a5f9f15c38 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1282-tty-serial-pl011-Also-unregister-pl011_axi_platform_.patch @@ -0,0 +1,22 @@ +From 0fb3c83a9fa3011cb735ec011b7582d4749957b2 Mon Sep 17 00:00:00 2001 +From: Dom Cobley +Date: Fri, 20 Sep 2024 12:21:27 +0100 +Subject: [PATCH 1282/1350] tty/serial: pl011: Also unregister + pl011_axi_platform_driver + +See: https://github.com/raspberrypi/linux/issues/6379 +Signed-off-by: Dom Cobley +--- + drivers/tty/serial/amba-pl011.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/tty/serial/amba-pl011.c ++++ b/drivers/tty/serial/amba-pl011.c +@@ -3122,6 +3122,7 @@ static int __init pl011_init(void) + static void __exit pl011_exit(void) + { + platform_driver_unregister(&arm_sbsa_uart_platform_driver); ++ platform_driver_unregister(&pl011_axi_platform_driver); + amba_driver_unregister(&pl011_driver); + } + diff --git a/target/linux/bcm27xx/patches-6.6/950-1283-overlays-wm8960-soundcard-Fix-clock-declaration.patch b/target/linux/bcm27xx/patches-6.6/950-1283-overlays-wm8960-soundcard-Fix-clock-declaration.patch new file mode 100644 index 00000000000..7a64d151c65 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1283-overlays-wm8960-soundcard-Fix-clock-declaration.patch @@ -0,0 +1,62 @@ +From 409a0e2fd41da7a4b04672136aa7d749988faf61 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 25 Sep 2024 16:41:55 +0100 +Subject: [PATCH 1283/1350] overlays: wm8960-soundcard: Fix clock declaration + +How did this ever work? The static-clock declaration is fine, but the +reference to it is attached to part of the simple-audio-card node, +rather than the instantiation of the codec driver (a subnode of the +I2C controller). + +Move the clock reference where it should be, and fix a few minor +cosmetic issues at the same time. + +Signed-off-by: Phil Elwell +--- + .../arm/boot/dts/overlays/wm8960-soundcard-overlay.dts | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/arch/arm/boot/dts/overlays/wm8960-soundcard-overlay.dts ++++ b/arch/arm/boot/dts/overlays/wm8960-soundcard-overlay.dts +@@ -13,7 +13,7 @@ + }; + + fragment@1 { +- target-path="/"; ++ target-path = "/"; + __overlay__ { + wm8960_mclk: wm8960_mclk { + compatible = "fixed-clock"; +@@ -29,17 +29,18 @@ + #size-cells = <0>; + status = "okay"; + +- wm8960: wm8960 { ++ wm8960: wm8960@1a { + compatible = "wlf,wm8960"; + reg = <0x1a>; + #sound-dai-cells = <0>; + AVDD-supply = <&vdd_5v0_reg>; + DVDD-supply = <&vdd_3v3_reg>; ++ clocks = <&wm8960_mclk>; ++ clock-names = "mclk"; + }; + }; + }; + +- + fragment@3 { + target = <&sound>; + slave_overlay: __overlay__ { +@@ -67,10 +68,9 @@ + simple-audio-card,cpu { + sound-dai = <&i2s_clk_producer>; + }; ++ + dailink0_slave: simple-audio-card,codec { + sound-dai = <&wm8960>; +- clocks = <&wm8960_mclk>; +- clock-names = "mclk"; + }; + }; + }; diff --git a/target/linux/bcm27xx/patches-6.6/950-1284-googlevoicehat-Fix-playback-muting-when-recording-is.patch b/target/linux/bcm27xx/patches-6.6/950-1284-googlevoicehat-Fix-playback-muting-when-recording-is.patch new file mode 100644 index 00000000000..3ecccd622ec --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1284-googlevoicehat-Fix-playback-muting-when-recording-is.patch @@ -0,0 +1,44 @@ +From d52d2bd85ad4d1cfc37a87a6b7bfcc37207c6025 Mon Sep 17 00:00:00 2001 +From: Ali Tekin <140681099+alitekin-saha@users.noreply.github.com> +Date: Thu, 26 Sep 2024 10:51:13 +0300 +Subject: [PATCH 1284/1350] googlevoicehat: Fix playback muting when recording + is stopped + +Fixed audio amplifier control logic in the voicehat trigger function +Resolves improper handling of the SDMODE pin, which caused issues when the microphone and speaker were used simultaneously. The playback stream check is now correctly based on `substream->stream == SNDRV_PCM_STREAM_PLAYBACK`, ensuring proper control of the audio amplifier. + +Signed-off-by: Ali Tekin +--- + sound/soc/bcm/googlevoicehat-codec.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +--- a/sound/soc/bcm/googlevoicehat-codec.c ++++ b/sound/soc/bcm/googlevoicehat-codec.c +@@ -95,8 +95,7 @@ static int voicehat_daiops_trigger(struc + struct snd_soc_dai *dai) + { + struct snd_soc_component *component = dai->component; +- struct voicehat_priv *voicehat = +- snd_soc_component_get_drvdata(component); ++ struct voicehat_priv *voicehat = snd_soc_component_get_drvdata(component); + + if (voicehat->sdmode_delay_jiffies == 0) + return 0; +@@ -109,7 +108,7 @@ static int voicehat_daiops_trigger(struc + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: +- if (dai->stream[SNDRV_PCM_STREAM_PLAYBACK].active) { ++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + dev_info(dai->dev, "Enabling audio amp...\n"); + queue_delayed_work( + system_power_efficient_wq, +@@ -120,7 +119,7 @@ static int voicehat_daiops_trigger(struc + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: +- if (dai->stream[SNDRV_PCM_STREAM_PLAYBACK].active) { ++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + cancel_delayed_work(&voicehat->enable_sdmode_work); + dev_info(dai->dev, "Disabling audio amp...\n"); + gpiod_set_value(voicehat->sdmode_gpio, 0); diff --git a/target/linux/bcm27xx/patches-6.6/950-1285-ASoC-bcm2835-i2s-Set-the-PERIOD_BYTES-min-to-256.patch b/target/linux/bcm27xx/patches-6.6/950-1285-ASoC-bcm2835-i2s-Set-the-PERIOD_BYTES-min-to-256.patch new file mode 100644 index 00000000000..5f148f4af3a --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1285-ASoC-bcm2835-i2s-Set-the-PERIOD_BYTES-min-to-256.patch @@ -0,0 +1,48 @@ +From a382d82b99a078f2ce65e78df9ba6db0d01c8ca3 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 24 Sep 2024 20:34:54 +0100 +Subject: [PATCH 1285/1350] ASoC: bcm2835-i2s: Set the PERIOD_BYTES min to 256 + +Commit [1] set the minimum PERIOD_BYTES value to the product of the DMA +burst size and 8. For the I2S interface on BCM2835 that equates to 16 +where it used to be 256. ffmpeg uses the minimum value as its preferred +value, leading to many, many very small periods, which affects +performance and leads to complaints about DTS timestamps. + +Restore the previous behaviour and performance by making the bcm2835-i2s +driver set a minimum PERIOD_BYTES value of 256. + +Link: https://github.com/raspberrypi/linux/issues/5709 + +[1] 300689fb04b3 ("ASoC: soc-generic-dmaengine-pcm: set +period_bytes_min based on maxburst") + +Signed-off-by: Phil Elwell +--- + sound/soc/bcm/bcm2835-i2s.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/sound/soc/bcm/bcm2835-i2s.c ++++ b/sound/soc/bcm/bcm2835-i2s.c +@@ -619,6 +619,10 @@ static int bcm2835_i2s_prepare(struct sn + struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); + uint32_t cs_reg; + ++ snd_pcm_hw_constraint_minmax(substream->runtime, ++ SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 256, ++ ~0); ++ + /* + * Clear both FIFOs if the one that should be started + * is not empty at the moment. This should only happen +@@ -700,6 +704,10 @@ static int bcm2835_i2s_startup(struct sn + /* Should this still be running stop it */ + bcm2835_i2s_stop_clock(dev); + ++ snd_pcm_hw_constraint_minmax(substream->runtime, ++ SNDRV_PCM_HW_PARAM_PERIOD_BYTES, ++ 256, ~0); ++ + /* Enable PCM block */ + regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, + BCM2835_I2S_EN, BCM2835_I2S_EN); diff --git a/target/linux/bcm27xx/patches-6.6/950-1286-clk-clk-rp1-Don-t-crash-on-duplicate-clocks.patch b/target/linux/bcm27xx/patches-6.6/950-1286-clk-clk-rp1-Don-t-crash-on-duplicate-clocks.patch new file mode 100644 index 00000000000..88a8774da04 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1286-clk-clk-rp1-Don-t-crash-on-duplicate-clocks.patch @@ -0,0 +1,30 @@ +From d290bef1f99e24cd590c64db149d007c6a631b65 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Mon, 16 Sep 2024 11:48:08 +0100 +Subject: [PATCH 1286/1350] clk: clk-rp1: Don't crash on duplicate clocks + +When using DTBs that don't match the kernel version, it's possible for +clock registration to fail. Handle that failure, in the hope that the +system can continue to boot, with a suitable error message. + +Link: https://github.com/raspberrypi/linux/issues/6321 + +Signed-off-by: Phil Elwell +--- + drivers/clk/clk-rp1.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/clk/clk-rp1.c ++++ b/drivers/clk/clk-rp1.c +@@ -2454,6 +2454,11 @@ static int rp1_clk_probe(struct platform + desc = &clk_desc_array[i]; + if (desc->clk_register && desc->data) { + hws[i] = desc->clk_register(clockman, desc->data); ++ if (IS_ERR_OR_NULL(hws[i])) { ++ pr_err("Failed to register RP1 clock '%s' (%ld) - wrong dtbs?\n", *(char **)desc->data, PTR_ERR(hws[i])); ++ hws[i] = NULL; ++ continue; ++ } + if (!strcmp(clk_hw_get_name(hws[i]), "clk_i2s")) { + clk_i2s = hws[i]; + clk_xosc = clk_hw_get_parent_by_index(clk_i2s, 0); diff --git a/target/linux/bcm27xx/patches-6.6/950-1287-drivers-media-imx500-Simplify-the-vblank-control-ini.patch b/target/linux/bcm27xx/patches-6.6/950-1287-drivers-media-imx500-Simplify-the-vblank-control-ini.patch new file mode 100644 index 00000000000..b4bb7d87da4 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1287-drivers-media-imx500-Simplify-the-vblank-control-ini.patch @@ -0,0 +1,98 @@ +From 0094eba3f2a4338cfa6854b0b5104d02ba0fa01f Mon Sep 17 00:00:00 2001 +From: Naushir Patuck +Date: Thu, 26 Sep 2024 13:12:23 +0100 +Subject: [PATCH 1287/1350] drivers: media: imx500: Simplify the vblank control + init + +Set the VBLANK control minimum and default values to IMX500_VBLANK_MIN +unconditionally everywhere. + +Remove the mode specific framerate_default parameter, it is now unused. + +Signed-off-by: Naushir Patuck +--- + drivers/media/i2c/imx500.c | 32 +++++--------------------------- + 1 file changed, 5 insertions(+), 27 deletions(-) + +--- a/drivers/media/i2c/imx500.c ++++ b/drivers/media/i2c/imx500.c +@@ -274,9 +274,6 @@ struct imx500_mode { + /* Analog crop rectangle. */ + struct v4l2_rect crop; + +- /* Default framerate. */ +- unsigned int framerate_default; +- + /* Default register values */ + struct imx500_reg_list reg_list; + }; +@@ -905,7 +902,6 @@ static const struct imx500_mode imx500_s + .width = 4056, + .height = 3040, + }, +- .framerate_default = 10, + .reg_list = { + .num_of_regs = ARRAY_SIZE(mode_4056x3040_regs), + .regs = mode_4056x3040_regs, +@@ -922,7 +918,6 @@ static const struct imx500_mode imx500_s + .width = 4056, + .height = 3040, + }, +- .framerate_default = 30, + .reg_list = { + .num_of_regs = ARRAY_SIZE(mode_2028x1520_regs), + .regs = mode_2028x1520_regs, +@@ -1744,28 +1739,11 @@ static int imx500_get_pad_format(struct + return 0; + } + +-static unsigned int imx500_get_frame_length(const struct imx500_mode *mode, +- unsigned int framerate_default) +-{ +- u64 frame_length; +- +- frame_length = IMX500_PIXEL_RATE; +- do_div(frame_length, (u64)framerate_default * mode->line_length_pix); +- +- if (WARN_ON(frame_length > IMX500_FRAME_LENGTH_MAX)) +- frame_length = IMX500_FRAME_LENGTH_MAX; +- +- return max_t(unsigned int, frame_length, mode->height); +-} +- + static void imx500_set_framing_limits(struct imx500 *imx500) + { +- unsigned int frm_length_default, hblank_min; ++ unsigned int hblank_min; + const struct imx500_mode *mode = imx500->mode; + +- frm_length_default = +- imx500_get_frame_length(mode, mode->framerate_default); +- + /* Default to no long exposure multiplier. */ + imx500->long_exp_shift = 0; + +@@ -1773,11 +1751,10 @@ static void imx500_set_framing_limits(st + __v4l2_ctrl_modify_range( + imx500->vblank, IMX500_VBLANK_MIN, + ((1 << IMX500_LONG_EXP_SHIFT_MAX) * IMX500_FRAME_LENGTH_MAX) - +- mode->height, +- 1, frm_length_default - mode->height); ++ mode->height, 1, IMX500_VBLANK_MIN); + + /* Setting this will adjust the exposure limits as well. */ +- __v4l2_ctrl_s_ctrl(imx500->vblank, frm_length_default - mode->height); ++ __v4l2_ctrl_s_ctrl(imx500->vblank, IMX500_VBLANK_MIN); + + hblank_min = mode->line_length_pix - mode->width; + __v4l2_ctrl_modify_range(imx500->hblank, hblank_min, hblank_min, 1, +@@ -2499,7 +2476,8 @@ static int imx500_init_controls(struct i + * in the imx500_set_framing_limits() call below. + */ + imx500->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx500_ctrl_ops, +- V4L2_CID_VBLANK, 0, 0xffff, 1, 0); ++ V4L2_CID_VBLANK, IMX500_VBLANK_MIN, ++ 0xffff, 1, IMX500_VBLANK_MIN); + imx500->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx500_ctrl_ops, + V4L2_CID_HBLANK, 0, 0xffff, 1, 0); + diff --git a/target/linux/bcm27xx/patches-6.6/950-1288-dts-overlay_map-ramoops-pi4-works-on-Pi-5.patch b/target/linux/bcm27xx/patches-6.6/950-1288-dts-overlay_map-ramoops-pi4-works-on-Pi-5.patch new file mode 100644 index 00000000000..43011bae396 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1288-dts-overlay_map-ramoops-pi4-works-on-Pi-5.patch @@ -0,0 +1,28 @@ +From 9557336c4fc4ac4606ac9e78c239aa689c26e870 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Thu, 26 Sep 2024 17:46:25 +0100 +Subject: [PATCH 1288/1350] dts: overlay_map: ramoops-pi4 works on Pi 5 + +Add the necessary overlay_map entries so that ramoops-pi4 is loaded +with dtoverlay=ramoops on Pi 5. + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/overlays/overlay_map.dts | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/arch/arm/boot/dts/overlays/overlay_map.dts ++++ b/arch/arm/boot/dts/overlays/overlay_map.dts +@@ -247,10 +247,12 @@ + ramoops { + bcm2835; + bcm2711 = "ramoops-pi4"; ++ bcm2712 = "ramoops-pi4"; + }; + + ramoops-pi4 { + bcm2711; ++ bcm2712; + }; + + rpi-cirrus-wm5102 { diff --git a/target/linux/bcm27xx/patches-6.6/950-1289-dts-align-PCI-BAR-allocation-on-bcm2711-and-bcm2712-.patch b/target/linux/bcm27xx/patches-6.6/950-1289-dts-align-PCI-BAR-allocation-on-bcm2711-and-bcm2712-.patch new file mode 100644 index 00000000000..c54f221a4fd --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1289-dts-align-PCI-BAR-allocation-on-bcm2711-and-bcm2712-.patch @@ -0,0 +1,109 @@ +From 2b5de12af9bb390239d5f3385c49e0c34f335de8 Mon Sep 17 00:00:00 2001 +From: Jonathan Bell +Date: Fri, 27 Sep 2024 10:59:02 +0100 +Subject: [PATCH 1289/1350] dts: align PCI BAR allocation on bcm2711 and + bcm2712 to start at 2GB + +Fold the Pi 5 mmio-hi compatibility option into the base DTB, and +shuffle the single MMIO window on bcm2711 to match. + +Certain devices cannot handle low addresses, e.g. by failing to +enumerate or failing to route the traffic appropriately. + +Link: https://github.com/raspberrypi/linux/issues/6134 +Link: https://github.com/raspberrypi/linux/issues/6278 + +Signed-off-by: Jonathan Bell +--- + .../arm/boot/dts/broadcom/bcm2711-rpi-ds.dtsi | 6 +++--- + arch/arm/boot/dts/overlays/README | 2 -- + .../overlays/pciex1-compat-pi5-overlay.dts | 20 ------------------- + arch/arm64/boot/dts/broadcom/bcm2712.dtsi | 10 ++++++---- + 4 files changed, 9 insertions(+), 29 deletions(-) + +--- a/arch/arm/boot/dts/broadcom/bcm2711-rpi-ds.dtsi ++++ b/arch/arm/boot/dts/broadcom/bcm2711-rpi-ds.dtsi +@@ -123,7 +123,7 @@ + + ranges = <0x0 0x7c000000 0x0 0xfc000000 0x0 0x03800000>, + <0x0 0x40000000 0x0 0xff800000 0x0 0x00800000>, +- <0x6 0x00000000 0x6 0x00000000 0x0 0x40000000>, ++ <0x6 0x00000000 0x6 0x00000000 0x0 0x80000000>, + <0x0 0x00000000 0x0 0x00000000 0x0 0xfc000000>; + dma-ranges = <0x4 0x7c000000 0x0 0xfc000000 0x0 0x03800000>, + <0x0 0x00000000 0x0 0x00000000 0x4 0x00000000>; +@@ -167,8 +167,8 @@ + + &pcie0 { + reg = <0x0 0x7d500000 0x0 0x9310>; +- ranges = <0x02000000 0x0 0xc0000000 0x6 0x00000000 +- 0x0 0x40000000>; ++ ranges = <0x02000000 0x0 0x80000000 0x6 0x00000000 ++ 0x0 0x80000000>; + }; + + &genet { +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -3617,8 +3617,6 @@ Params: l1ss Enable A + the MSI-MIP peripheral. Use if a) more than 8 + interrupt vectors are required or b) the EP + requires DMA and MSI addresses to be 32bit. +- mmio-hi Move the start of outbound 32bit addresses to +- 2GB and expand 64bit outbound space to 14GB. + + + [ The pcf2127-rtc overlay has been deleted. See i2c-rtc. ] +--- a/arch/arm/boot/dts/overlays/pciex1-compat-pi5-overlay.dts ++++ b/arch/arm/boot/dts/overlays/pciex1-compat-pi5-overlay.dts +@@ -32,29 +32,9 @@ + }; + }; + +- /* +- * Shift the start of the 32bit outbound window to 2GB, +- * so there are no BARs starting at 0x0. Expand the 64bit +- * outbound window to use the spare 2GB. +- */ +- fragment@3 { +- target = <&pciex1>; +- __dormant__ { +- #address-cells = <3>; +- #size-cells = <2>; +- ranges = <0x02000000 0x00 0x80000000 +- 0x1b 0x80000000 +- 0x00 0x7ffffffc>, +- <0x43000000 0x04 0x00000000 +- 0x18 0x00000000 +- 0x03 0x80000000>; +- }; +- }; +- + __overrides__ { + l1ss = <0>, "+0"; + no-l0s = <0>, "+1"; + no-mip = <0>, "+2"; +- mmio-hi = <0>, "+3"; + }; + }; +--- a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi ++++ b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi +@@ -1052,12 +1052,14 @@ + msi-controller; + msi-parent = <&mip1>; + +- ranges = <0x02000000 0x00 0x00000000 +- 0x1b 0x00000000 +- 0x00 0xfffffffc>, ++ // 2GB, 32-bit, non-prefetchable at PCIe 00_80000000 ++ ranges = <0x02000000 0x00 0x80000000 ++ 0x1b 0x80000000 ++ 0x00 0x80000000>, ++ // 14GB, 64-bit, prefetchable at PCIe 04_00000000 + <0x43000000 0x04 0x00000000 + 0x18 0x00000000 +- 0x03 0x00000000>; ++ 0x03 0x80000000>; + + dma-ranges = <0x03000000 0x10 0x00000000 + 0x00 0x00000000 diff --git a/target/linux/bcm27xx/patches-6.6/950-1290-overlays-Add-Pineboards-HatDrive-POE-6257.patch b/target/linux/bcm27xx/patches-6.6/950-1290-overlays-Add-Pineboards-HatDrive-POE-6257.patch new file mode 100644 index 00000000000..583602d0e0c --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1290-overlays-Add-Pineboards-HatDrive-POE-6257.patch @@ -0,0 +1,61 @@ +From 35b3f98bb2bfb80a718c52ba49c167da6c78d2ea Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Micha=C5=82=20Gapi=C5=84ski?= + +Date: Mon, 30 Sep 2024 16:47:20 +0200 +Subject: [PATCH 1290/1350] overlays: Add Pineboards HatDrive! POE+ (#6257) + +overlays: Add Pineboards HatDrive! POE+ +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 6 ++++++ + .../pineboards-hatdrive-poe-plus-overlay.dts | 19 +++++++++++++++++++ + 3 files changed, 26 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/pineboards-hatdrive-poe-plus-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -204,6 +204,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + pifi-mini-210.dtbo \ + piglow.dtbo \ + pineboards-hat-ai.dtbo \ ++ pineboards-hatdrive-poe-plus.dtbo \ + piscreen.dtbo \ + piscreen2r.dtbo \ + pisound.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -3703,6 +3703,12 @@ Load: dtoverlay=pineboards-hat-ai + Params: + + ++Name: pineboards-hatdrive-poe-plus ++Info: Configures the Pineboards HatDrive! PoE+ ++Load: dtoverlay=pineboards-hatdrive-poe-plus ++Params: ++ ++ + Name: piscreen + Info: PiScreen display by OzzMaker.com + Load: dtoverlay=piscreen,= +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/pineboards-hatdrive-poe-plus-overlay.dts +@@ -0,0 +1,19 @@ ++/* ++ * Device Tree overlay for Pineboards HatDrive! PoE+. ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2712"; ++ ++ fragment@0 { ++ target-path = "/chosen"; ++ __overlay__ { ++ power: power { ++ hat_current_supply = <5000>; ++ }; ++ }; ++ }; ++}; diff --git a/target/linux/bcm27xx/patches-6.6/950-1296-dtoverlays-Correct-vc4-kms-dpi-generic-for-width-hei.patch b/target/linux/bcm27xx/patches-6.6/950-1296-dtoverlays-Correct-vc4-kms-dpi-generic-for-width-hei.patch new file mode 100644 index 00000000000..f56147c8f7e --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1296-dtoverlays-Correct-vc4-kms-dpi-generic-for-width-hei.patch @@ -0,0 +1,31 @@ +From 50a6e5cf28a24e7f4192ad6f70f472eca2097cc6 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Wed, 2 Oct 2024 16:36:45 +0100 +Subject: [PATCH 1296/1350] dtoverlays: Correct vc4-kms-dpi-generic for + [width|height]-mm + +These two overrides were updating the &panel node from +vc4-kms-dpi.dtsi, when fragment0 from the vc4-kms-dpi-generic +was also updating the same node. Application order meant that +the override value was overwritten. + +Correct the target. + +Signed-off-by: Dave Stevenson +--- + arch/arm/boot/dts/overlays/vc4-kms-dpi-generic-overlay.dts | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/arm/boot/dts/overlays/vc4-kms-dpi-generic-overlay.dts ++++ b/arch/arm/boot/dts/overlays/vc4-kms-dpi-generic-overlay.dts +@@ -60,8 +60,8 @@ + de-invert = <&timing>, "de-active:0=0"; + pixclk-invert = <&timing>, "pixelclk-active:0=0"; + +- width-mm = <&panel>, "width-mm:0"; +- height-mm = <&panel>, "height-mm:0"; ++ width-mm = <&panel_generic>, "width-mm:0"; ++ height-mm = <&panel_generic>, "height-mm:0"; + + rgb565 = <&panel_generic>, "bus-format:0=0x1017", + <&dpi_node_generic>, "pinctrl-0:0=",<&dpi_16bit_gpio0>; diff --git a/target/linux/bcm27xx/patches-6.6/950-1297-dts-bcm2712-rpi-Add-four-missing-GPIOs-to-2712D0.patch b/target/linux/bcm27xx/patches-6.6/950-1297-dts-bcm2712-rpi-Add-four-missing-GPIOs-to-2712D0.patch new file mode 100644 index 00000000000..2ccd898f847 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1297-dts-bcm2712-rpi-Add-four-missing-GPIOs-to-2712D0.patch @@ -0,0 +1,32 @@ +From e044f6af1b2b41bc2212551b4fd6353469cb7263 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Thu, 12 Sep 2024 16:29:57 +0100 +Subject: [PATCH 1297/1350] dts: bcm2712-rpi: Add four missing GPIOs to 2712D0 + +It's useful for gpioinfo and pinctrl to distinguish between unused and +absent GPIOs. We use "-" for the former and "" for the latter. +With this convention, gpioinfo shows absent GPIOs as "unnamed", while +pinctrl omits them altogether. + +Signed-off-by: Phil Elwell +--- + arch/arm64/boot/dts/broadcom/bcm2712d0-rpi-5-b.dts | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/arch/arm64/boot/dts/broadcom/bcm2712d0-rpi-5-b.dts ++++ b/arch/arm64/boot/dts/broadcom/bcm2712d0-rpi-5-b.dts +@@ -15,10 +15,10 @@ + "", // GPIO_007 + "", // GPIO_008 + "", // GPIO_009 +- "", // GPIO_010 +- "", // GPIO_011 +- "", // GPIO_012 +- "", // GPIO_013 ++ "-", // GPIO_010 ++ "-", // GPIO_011 ++ "-", // GPIO_012 ++ "-", // GPIO_013 + "PCIE_SDA", // GPIO_014 + "PCIE_SCL", // GPIO_015 + "", // GPIO_016 diff --git a/target/linux/bcm27xx/patches-6.6/950-1298-arm64-dts-Add-preliminary-bcm2712-rpi-500-dts.patch b/target/linux/bcm27xx/patches-6.6/950-1298-arm64-dts-Add-preliminary-bcm2712-rpi-500-dts.patch new file mode 100644 index 00000000000..6d961a760ee --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1298-arm64-dts-Add-preliminary-bcm2712-rpi-500-dts.patch @@ -0,0 +1,169 @@ +From 3be1a52ad9e3ae7b0e16eb20c77d9df60e29f139 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 10 Sep 2024 14:07:16 +0100 +Subject: [PATCH 1298/1350] arm64: dts: Add preliminary bcm2712-rpi-500 dts + +Add the first DTS file for Pi 500. + +Signed-off-by: Phil Elwell +--- + arch/arm64/boot/dts/broadcom/Makefile | 1 + + .../boot/dts/broadcom/bcm2712-rpi-500.dts | 142 ++++++++++++++++++ + 2 files changed, 143 insertions(+) + create mode 100644 arch/arm64/boot/dts/broadcom/bcm2712-rpi-500.dts + +--- a/arch/arm64/boot/dts/broadcom/Makefile ++++ b/arch/arm64/boot/dts/broadcom/Makefile +@@ -22,6 +22,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += bcm2711-rp + dtb-$(CONFIG_ARCH_BCM2835) += bcm2711-rpi-cm4s.dtb + dtb-$(CONFIG_ARCH_BCM2835) += bcm2712-rpi-5-b.dtb + dtb-$(CONFIG_ARCH_BCM2835) += bcm2712d0-rpi-5-b.dtb ++dtb-$(CONFIG_ARCH_BCM2835) += bcm2712-rpi-500.dtb + dtb-$(CONFIG_ARCH_BCM2835) += bcm2712-rpi-cm5-cm5io.dtb + dtb-$(CONFIG_ARCH_BCM2835) += bcm2712-rpi-cm5-cm4io.dtb + dtb-$(CONFIG_ARCH_BCM2835) += bcm2712-rpi-cm5l-cm5io.dtb +--- /dev/null ++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-500.dts +@@ -0,0 +1,142 @@ ++// SPDX-License-Identifier: GPL-2.0 ++#include "bcm2712d0-rpi-5-b.dts" ++ ++/ { ++ compatible = "raspberrypi,500", "brcm,bcm2712"; ++ model = "Raspberry Pi 500"; ++}; ++ ++&pwr_key { ++ debounce-interval = <400>; ++}; ++ ++&gio { ++ gpio-line-names = ++ "", // GPIO_000 ++ "2712_BOOT_CS_N", // GPIO_001 ++ "2712_BOOT_MISO", // GPIO_002 ++ "2712_BOOT_MOSI", // GPIO_003 ++ "2712_BOOT_SCLK", // GPIO_004 ++ "", // GPIO_005 ++ "", // GPIO_006 ++ "", // GPIO_007 ++ "", // GPIO_008 ++ "", // GPIO_009 ++ "-", // GPIO_010 ++ "-", // GPIO_011 ++ "-", // GPIO_012 ++ "-", // GPIO_013 ++ "M2_DET_WAKE", // GPIO_014 ++ "M2_PWR_EN", // GPIO_015 ++ "", // GPIO_016 ++ "", // GPIO_017 ++ "KEYB_BOOTSEL", // GPIO_018 ++ "-", // GPIO_019 ++ "PWR_GPIO", // GPIO_020 ++ "KEYB_RUN", // GPIO_021 ++ "-", // GPIO_022 ++ "-", // GPIO_023 ++ "BT_RTS", // GPIO_024 ++ "BT_CTS", // GPIO_025 ++ "BT_TXD", // GPIO_026 ++ "BT_RXD", // GPIO_027 ++ "WL_ON", // GPIO_028 ++ "BT_ON", // GPIO_029 ++ "WIFI_SDIO_CLK", // GPIO_030 ++ "WIFI_SDIO_CMD", // GPIO_031 ++ "WIFI_SDIO_D0", // GPIO_032 ++ "WIFI_SDIO_D1", // GPIO_033 ++ "WIFI_SDIO_D2", // GPIO_034 ++ "WIFI_SDIO_D3"; // GPIO_035 ++}; ++ ++&gio_aon { ++ gpio-line-names = ++ "RP1_SDA", // AON_GPIO_00 ++ "RP1_SCL", // AON_GPIO_01 ++ "RP1_RUN", // AON_GPIO_02 ++ "SD_IOVDD_SEL", // AON_GPIO_03 ++ "SD_PWR_ON", // AON_GPIO_04 ++ "SD_CDET_N", // AON_GPIO_05 ++ "SD_FLG_N", // AON_GPIO_06 ++ "", // AON_GPIO_07 ++ "2712_WAKE", // AON_GPIO_08 ++ "2712_STAT_LED", // AON_GPIO_09 ++ "", // AON_GPIO_10 ++ "", // AON_GPIO_11 ++ "PMIC_INT", // AON_GPIO_12 ++ "UART_TX_FS", // AON_GPIO_13 ++ "UART_RX_FS", // AON_GPIO_14 ++ "", // AON_GPIO_15 ++ "", // AON_GPIO_16 ++ ++ // Pad bank0 out to 32 entries ++ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ++ ++ "HDMI0_SCL", // AON_SGPIO_00 ++ "HDMI0_SDA", // AON_SGPIO_01 ++ "HDMI1_SCL", // AON_SGPIO_02 ++ "HDMI1_SDA", // AON_SGPIO_03 ++ "PMIC_SCL", // AON_SGPIO_04 ++ "PMIC_SDA"; // AON_SGPIO_05 ++}; ++ ++&rp1_gpio { ++ gpio-line-names = ++ "ID_SDA", // GPIO0 ++ "ID_SCL", // GPIO1 ++ "GPIO2", // GPIO2 ++ "GPIO3", // GPIO3 ++ "GPIO4", // GPIO4 ++ "GPIO5", // GPIO5 ++ "GPIO6", // GPIO6 ++ "GPIO7", // GPIO7 ++ "GPIO8", // GPIO8 ++ "GPIO9", // GPIO9 ++ "GPIO10", // GPIO10 ++ "GPIO11", // GPIO11 ++ "GPIO12", // GPIO12 ++ "GPIO13", // GPIO13 ++ "GPIO14", // GPIO14 ++ "GPIO15", // GPIO15 ++ "GPIO16", // GPIO16 ++ "GPIO17", // GPIO17 ++ "GPIO18", // GPIO18 ++ "GPIO19", // GPIO19 ++ "GPIO20", // GPIO20 ++ "GPIO21", // GPIO21 ++ "GPIO22", // GPIO22 ++ "GPIO23", // GPIO23 ++ "GPIO24", // GPIO24 ++ "GPIO25", // GPIO25 ++ "GPIO26", // GPIO26 ++ "GPIO27", // GPIO27 ++ ++ "PCIE_RP1_WAKE", // GPIO28 ++ "-", // GPIO29 ++ "HOST_SDA", // GPIO30 ++ "HOST_SCL", // GPIO31 ++ "ETH_RST_N", // GPIO32 ++ "PCIE_DET_WAKE", // GPIO33 ++ ++ "-", // GPIO34 ++ "-", // GPIO35 ++ "RP1_PCIE_CLKREQ_N", // GPIO36 ++ "-", // GPIO37 ++ "-", // GPIO38 ++ "-", // GPIO39 ++ "CD1_SDA", // GPIO40 ++ "CD1_SCL", // GPIO41 ++ "USB_VBUS_EN", // GPIO42 ++ "USB_OC_N", // GPIO43 ++ "RP1_STAT_LED", // GPIO44 ++ "-", // GPIO45 ++ "-", // GPIO46 ++ "HOST_WAKE", // GPIO47 ++ "-", // GPIO48 ++ "EN_MAX_USB_CUR", // GPIO49 ++ "-", // GPIO50 ++ "-", // GPIO51 ++ "-", // GPIO52 ++ "-"; // GPIO53 ++}; diff --git a/target/linux/bcm27xx/patches-6.6/950-1301-dts-2712-Reduce-default-cma-usage-on-Pi5.patch b/target/linux/bcm27xx/patches-6.6/950-1301-dts-2712-Reduce-default-cma-usage-on-Pi5.patch new file mode 100644 index 00000000000..bb26a893456 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1301-dts-2712-Reduce-default-cma-usage-on-Pi5.patch @@ -0,0 +1,30 @@ +From 3edaa3875fbeb0b2effd77c62baabf2933efc6ef Mon Sep 17 00:00:00 2001 +From: Dom Cobley +Date: Fri, 13 Sep 2024 17:23:58 +0100 +Subject: [PATCH 1301/1350] dts: 2712: Reduce default cma usage on Pi5 + +Significant cma shouldn't really be needed on Pi5 as the hardware +blocks support iommu and can access system memory. + +We've migrated codec and camera support to system memory, and 3d +has always (even on Pi4) used system memory. + +A large cma block causes issues with enabling NUMA on a low +memory (2G) Pi5, as cma cannot span numa regions. + +Signed-off-by: Dom Cobley +--- + arch/arm/boot/dts/overlays/vc4-kms-v3d-pi5-overlay.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm/boot/dts/overlays/vc4-kms-v3d-pi5-overlay.dts ++++ b/arch/arm/boot/dts/overlays/vc4-kms-v3d-pi5-overlay.dts +@@ -3,7 +3,7 @@ + #include "cma-overlay.dts" + + &frag0 { +- size = <((320-4)*1024*1024)>; ++ size = <(64*1024*1024)>; + }; + + / { diff --git a/target/linux/bcm27xx/patches-6.6/950-1305-dts-bcm2712d0-Add-non-d0-vc6-compatible-string.patch b/target/linux/bcm27xx/patches-6.6/950-1305-dts-bcm2712d0-Add-non-d0-vc6-compatible-string.patch new file mode 100644 index 00000000000..4660c8f4357 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1305-dts-bcm2712d0-Add-non-d0-vc6-compatible-string.patch @@ -0,0 +1,39 @@ +From d69bca1f0425be1a42f7ad1e3cff5313ba7c122a Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 9 Oct 2024 15:13:14 +0100 +Subject: [PATCH 1305/1350] dts: bcm2712d0: Add non-d0 vc6 compatible string + +Although the VC4/VC6 driver requires a special compatible string for the +"d0" stepping, the removal of the old compatible string upsets Mesa. + +Satisfy both requirements by adding the old "brcm,bcm2712-vc6" string +as a fallback. + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/overlays/bcm2712d0-overlay.dts | 2 +- + arch/arm64/boot/dts/broadcom/bcm2712d0-rpi-5-b.dts | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/arm/boot/dts/overlays/bcm2712d0-overlay.dts ++++ b/arch/arm/boot/dts/overlays/bcm2712d0-overlay.dts +@@ -41,7 +41,7 @@ + fragment@4 { + target = <&vc4>; + __overlay__ { +- compatible = "brcm,bcm2712d0-vc6"; ++ compatible = "brcm,bcm2712d0-vc6", "brcm,bcm2712-vc6"; + }; + }; + +--- a/arch/arm64/boot/dts/broadcom/bcm2712d0-rpi-5-b.dts ++++ b/arch/arm64/boot/dts/broadcom/bcm2712d0-rpi-5-b.dts +@@ -87,7 +87,7 @@ + }; + + &vc4 { +- compatible = "brcm,bcm2712d0-vc6"; ++ compatible = "brcm,bcm2712d0-vc6", "brcm,bcm2712-vc6"; + }; + + &uart10 { diff --git a/target/linux/bcm27xx/patches-6.6/950-1312-Reapply-dtoverlays-Convert-SenseHAT-overlays-to-use-.patch b/target/linux/bcm27xx/patches-6.6/950-1312-Reapply-dtoverlays-Convert-SenseHAT-overlays-to-use-.patch new file mode 100644 index 00000000000..9501067d68f --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1312-Reapply-dtoverlays-Convert-SenseHAT-overlays-to-use-.patch @@ -0,0 +1,100 @@ +From 9a86952570b925e68dfd30a12642000353242745 Mon Sep 17 00:00:00 2001 +From: Dom Cobley +Date: Thu, 10 Oct 2024 17:16:08 +0100 +Subject: [PATCH 1312/1350] Reapply "dtoverlays: Convert SenseHAT overlays to + use MFD and upstream drivers" + +This reverts commit 82a50e430ef1d6eb37d78e25aa572c1f6ea56160. +--- + .../boot/dts/overlays/rpi-sense-overlay.dts | 28 +++++++++++++++++-- + .../dts/overlays/rpi-sense-v2-overlay.dts | 28 +++++++++++++++++-- + 2 files changed, 50 insertions(+), 6 deletions(-) + +--- a/arch/arm/boot/dts/overlays/rpi-sense-overlay.dts ++++ b/arch/arm/boot/dts/overlays/rpi-sense-overlay.dts +@@ -12,11 +12,23 @@ + #size-cells = <0>; + status = "okay"; + +- rpi-sense@46 { +- compatible = "rpi,rpi-sense"; ++ sensehat@46 { ++ compatible = "raspberrypi,sensehat"; + reg = <0x46>; +- keys-int-gpios = <&gpio 23 1>; ++ interrupt-parent = <&gpio>; + status = "okay"; ++ ++ display { ++ compatible = "raspberrypi,rpi-sense-fb"; ++ status = "okay"; ++ }; ++ joystick { ++ compatible = "raspberrypi,sensehat-joystick"; ++ interrupts = <23 1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sensehat_pins>; ++ status = "okay"; ++ }; + }; + + lsm9ds1-magn@1c { +@@ -44,4 +56,14 @@ + }; + }; + }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ sensehat_pins: sensehat_pins { ++ brcm,pins = <23>; ++ brcm,function = <0>; ++ }; ++ }; ++ }; + }; +--- a/arch/arm/boot/dts/overlays/rpi-sense-v2-overlay.dts ++++ b/arch/arm/boot/dts/overlays/rpi-sense-v2-overlay.dts +@@ -12,11 +12,23 @@ + #size-cells = <0>; + status = "okay"; + +- rpi-sense@46 { +- compatible = "rpi,rpi-sense"; ++ sensehat@46 { ++ compatible = "raspberrypi,sensehat"; + reg = <0x46>; +- keys-int-gpios = <&gpio 23 1>; ++ interrupt-parent = <&gpio>; + status = "okay"; ++ ++ display { ++ compatible = "raspberrypi,rpi-sense-fb"; ++ status = "okay"; ++ }; ++ joystick { ++ compatible = "raspberrypi,sensehat-joystick"; ++ interrupts = <23 1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sensehat_pins>; ++ status = "okay"; ++ }; + }; + + lsm9ds1-magn@1c { +@@ -44,4 +56,14 @@ + }; + }; + }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ sensehat_pins: sensehat_pins { ++ brcm,pins = <23>; ++ brcm,function = <0>; ++ }; ++ }; ++ }; + }; diff --git a/target/linux/bcm27xx/patches-6.6/950-1313-Reapply-drivers-Remove-downstream-SenseHAT-core-and-.patch b/target/linux/bcm27xx/patches-6.6/950-1313-Reapply-drivers-Remove-downstream-SenseHAT-core-and-.patch new file mode 100644 index 00000000000..714123d3ded --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1313-Reapply-drivers-Remove-downstream-SenseHAT-core-and-.patch @@ -0,0 +1,608 @@ +From 9fb57f6b8920a8aceb74ceb3e171a7e5769205a5 Mon Sep 17 00:00:00 2001 +From: Dom Cobley +Date: Thu, 10 Oct 2024 17:18:39 +0100 +Subject: [PATCH 1313/1350] Reapply "drivers: Remove downstream SenseHAT core + and joystick drivers" + +This reverts commit e6493e2d6a1f572fbb4a1d724e54715cb748b424. +--- + drivers/input/joystick/Kconfig | 8 -- + drivers/input/joystick/Makefile | 1 - + drivers/input/joystick/rpisense-js.c | 153 --------------------- + drivers/mfd/Kconfig | 8 -- + drivers/mfd/Makefile | 1 - + drivers/mfd/rpisense-core.c | 163 ----------------------- + drivers/video/fbdev/Kconfig | 4 +- + drivers/video/fbdev/rpisense-fb.c | 53 ++++---- + include/linux/mfd/rpisense/core.h | 47 ------- + include/linux/mfd/rpisense/framebuffer.h | 5 +- + 10 files changed, 32 insertions(+), 411 deletions(-) + delete mode 100644 drivers/input/joystick/rpisense-js.c + delete mode 100644 drivers/mfd/rpisense-core.c + delete mode 100644 include/linux/mfd/rpisense/core.h + +--- a/drivers/input/joystick/Kconfig ++++ b/drivers/input/joystick/Kconfig +@@ -412,12 +412,4 @@ config JOYSTICK_SENSEHAT + To compile this driver as a module, choose M here: the + module will be called sensehat_joystick. + +-config JOYSTICK_RPISENSE +- tristate "Raspberry Pi Sense HAT joystick" +- depends on GPIOLIB && INPUT +- select MFD_RPISENSE_CORE +- +- help +- This is the joystick driver for the Raspberry Pi Sense HAT +- + endif +--- a/drivers/input/joystick/Makefile ++++ b/drivers/input/joystick/Makefile +@@ -40,4 +40,3 @@ obj-$(CONFIG_JOYSTICK_WARRIOR) += warri + obj-$(CONFIG_JOYSTICK_WALKERA0701) += walkera0701.o + obj-$(CONFIG_JOYSTICK_XPAD) += xpad.o + obj-$(CONFIG_JOYSTICK_ZHENHUA) += zhenhua.o +-obj-$(CONFIG_JOYSTICK_RPISENSE) += rpisense-js.o +--- a/drivers/input/joystick/rpisense-js.c ++++ /dev/null +@@ -1,153 +0,0 @@ +-/* +- * Raspberry Pi Sense HAT joystick driver +- * http://raspberrypi.org +- * +- * Copyright (C) 2015 Raspberry Pi +- * +- * Author: Serge Schneider +- * +- * This program is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License as published by the +- * Free Software Foundation; either version 2 of the License, or (at your +- * option) any later version. +- * +- */ +- +-#include +- +-#include +-#include +- +-static struct rpisense *rpisense; +-static unsigned char keymap[5] = {KEY_DOWN, KEY_RIGHT, KEY_UP, KEY_ENTER, KEY_LEFT,}; +- +-static void keys_work_fn(struct work_struct *work) +-{ +- int i; +- static s32 prev_keys; +- struct rpisense_js *rpisense_js = &rpisense->joystick; +- s32 keys = rpisense_reg_read(rpisense, RPISENSE_KEYS); +- s32 changes = keys ^ prev_keys; +- +- prev_keys = keys; +- for (i = 0; i < 5; i++) { +- if (changes & 1) { +- input_report_key(rpisense_js->keys_dev, +- keymap[i], keys & 1); +- } +- changes >>= 1; +- keys >>= 1; +- } +- input_sync(rpisense_js->keys_dev); +-} +- +-static irqreturn_t keys_irq_handler(int irq, void *pdev) +-{ +- struct rpisense_js *rpisense_js = &rpisense->joystick; +- +- schedule_work(&rpisense_js->keys_work_s); +- return IRQ_HANDLED; +-} +- +-static int rpisense_js_probe(struct platform_device *pdev) +-{ +- int ret; +- int i; +- struct rpisense_js *rpisense_js; +- +- rpisense = rpisense_get_dev(); +- rpisense_js = &rpisense->joystick; +- +- INIT_WORK(&rpisense_js->keys_work_s, keys_work_fn); +- +- rpisense_js->keys_dev = input_allocate_device(); +- if (!rpisense_js->keys_dev) { +- dev_err(&pdev->dev, "Could not allocate input device.\n"); +- return -ENOMEM; +- } +- +- rpisense_js->keys_dev->evbit[0] = BIT_MASK(EV_KEY); +- for (i = 0; i < ARRAY_SIZE(keymap); i++) { +- set_bit(keymap[i], +- rpisense_js->keys_dev->keybit); +- } +- +- rpisense_js->keys_dev->name = "Raspberry Pi Sense HAT Joystick"; +- rpisense_js->keys_dev->phys = "rpi-sense-joy/input0"; +- rpisense_js->keys_dev->id.bustype = BUS_I2C; +- rpisense_js->keys_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); +- rpisense_js->keys_dev->keycode = keymap; +- rpisense_js->keys_dev->keycodesize = sizeof(unsigned char); +- rpisense_js->keys_dev->keycodemax = ARRAY_SIZE(keymap); +- +- ret = input_register_device(rpisense_js->keys_dev); +- if (ret) { +- dev_err(&pdev->dev, "Could not register input device.\n"); +- goto err_keys_alloc; +- } +- +- ret = gpiod_direction_input(rpisense_js->keys_desc); +- if (ret) { +- dev_err(&pdev->dev, "Could not set keys-int direction.\n"); +- goto err_keys_reg; +- } +- +- rpisense_js->keys_irq = gpiod_to_irq(rpisense_js->keys_desc); +- if (rpisense_js->keys_irq < 0) { +- dev_err(&pdev->dev, "Could not determine keys-int IRQ.\n"); +- ret = rpisense_js->keys_irq; +- goto err_keys_reg; +- } +- +- ret = devm_request_irq(&pdev->dev, rpisense_js->keys_irq, +- keys_irq_handler, IRQF_TRIGGER_RISING, +- "keys", &pdev->dev); +- if (ret) { +- dev_err(&pdev->dev, "IRQ request failed.\n"); +- goto err_keys_reg; +- } +- return 0; +-err_keys_reg: +- input_unregister_device(rpisense_js->keys_dev); +-err_keys_alloc: +- input_free_device(rpisense_js->keys_dev); +- return ret; +-} +- +-static int rpisense_js_remove(struct platform_device *pdev) +-{ +- struct rpisense_js *rpisense_js = &rpisense->joystick; +- +- input_unregister_device(rpisense_js->keys_dev); +- input_free_device(rpisense_js->keys_dev); +- return 0; +-} +- +-#ifdef CONFIG_OF +-static const struct of_device_id rpisense_js_id[] = { +- { .compatible = "rpi,rpi-sense-js" }, +- { }, +-}; +-MODULE_DEVICE_TABLE(of, rpisense_js_id); +-#endif +- +-static struct platform_device_id rpisense_js_device_id[] = { +- { .name = "rpi-sense-js" }, +- { }, +-}; +-MODULE_DEVICE_TABLE(platform, rpisense_js_device_id); +- +-static struct platform_driver rpisense_js_driver = { +- .probe = rpisense_js_probe, +- .remove = rpisense_js_remove, +- .driver = { +- .name = "rpi-sense-js", +- .owner = THIS_MODULE, +- }, +-}; +- +-module_platform_driver(rpisense_js_driver); +- +-MODULE_DESCRIPTION("Raspberry Pi Sense HAT joystick driver"); +-MODULE_AUTHOR("Serge Schneider "); +-MODULE_LICENSE("GPL"); +--- a/drivers/mfd/Kconfig ++++ b/drivers/mfd/Kconfig +@@ -11,14 +11,6 @@ config MFD_CORE + select IRQ_DOMAIN + default n + +-config MFD_RPISENSE_CORE +- tristate "Raspberry Pi Sense HAT core functions" +- depends on I2C +- select MFD_CORE +- help +- This is the core driver for the Raspberry Pi Sense HAT. This provides +- the necessary functions to communicate with the hardware. +- + config MFD_CS5535 + tristate "AMD CS5535 and CS5536 southbridge core functions" + select MFD_CORE +--- a/drivers/mfd/Makefile ++++ b/drivers/mfd/Makefile +@@ -268,7 +268,6 @@ obj-$(CONFIG_MFD_STMFX) += stmfx.o + obj-$(CONFIG_MFD_KHADAS_MCU) += khadas-mcu.o + obj-$(CONFIG_MFD_ACER_A500_EC) += acer-ec-a500.o + obj-$(CONFIG_MFD_QCOM_PM8008) += qcom-pm8008.o +-obj-$(CONFIG_MFD_RPISENSE_CORE) += rpisense-core.o + + obj-$(CONFIG_SGI_MFD_IOC3) += ioc3.o + obj-$(CONFIG_MFD_SIMPLE_MFD_I2C) += simple-mfd-i2c.o +--- a/drivers/mfd/rpisense-core.c ++++ /dev/null +@@ -1,163 +0,0 @@ +-/* +- * Raspberry Pi Sense HAT core driver +- * http://raspberrypi.org +- * +- * Copyright (C) 2015 Raspberry Pi +- * +- * Author: Serge Schneider +- * +- * This program is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License as published by the +- * Free Software Foundation; either version 2 of the License, or (at your +- * option) any later version. +- * +- * This driver is based on wm8350 implementation. +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-static struct rpisense *rpisense; +- +-static void rpisense_client_dev_register(struct rpisense *rpisense, +- const char *name, +- struct platform_device **pdev) +-{ +- int ret; +- +- *pdev = platform_device_alloc(name, -1); +- if (*pdev == NULL) { +- dev_err(rpisense->dev, "Failed to allocate %s\n", name); +- return; +- } +- +- (*pdev)->dev.parent = rpisense->dev; +- platform_set_drvdata(*pdev, rpisense); +- ret = platform_device_add(*pdev); +- if (ret != 0) { +- dev_err(rpisense->dev, "Failed to register %s: %d\n", +- name, ret); +- platform_device_put(*pdev); +- *pdev = NULL; +- } +-} +- +-static int rpisense_probe(struct i2c_client *i2c) +-{ +- int ret; +- struct rpisense_js *rpisense_js; +- +- rpisense = devm_kzalloc(&i2c->dev, sizeof(struct rpisense), GFP_KERNEL); +- if (rpisense == NULL) +- return -ENOMEM; +- +- i2c_set_clientdata(i2c, rpisense); +- rpisense->dev = &i2c->dev; +- rpisense->i2c_client = i2c; +- +- ret = rpisense_reg_read(rpisense, RPISENSE_WAI); +- if (ret > 0) { +- if (ret != 's') +- return -EINVAL; +- } else { +- return ret; +- } +- ret = rpisense_reg_read(rpisense, RPISENSE_VER); +- if (ret < 0) +- return ret; +- +- dev_info(rpisense->dev, +- "Raspberry Pi Sense HAT firmware version %i\n", ret); +- +- rpisense_js = &rpisense->joystick; +- rpisense_js->keys_desc = devm_gpiod_get(&i2c->dev, +- "keys-int", GPIOD_IN); +- if (IS_ERR(rpisense_js->keys_desc)) { +- dev_warn(&i2c->dev, "Failed to get keys-int descriptor.\n"); +- rpisense_js->keys_desc = gpio_to_desc(23); +- if (rpisense_js->keys_desc == NULL) { +- dev_err(&i2c->dev, "GPIO23 fallback failed.\n"); +- return PTR_ERR(rpisense_js->keys_desc); +- } +- } +- rpisense_client_dev_register(rpisense, "rpi-sense-js", +- &(rpisense->joystick.pdev)); +- rpisense_client_dev_register(rpisense, "rpi-sense-fb", +- &(rpisense->framebuffer.pdev)); +- +- return 0; +-} +- +-static void rpisense_remove(struct i2c_client *i2c) +-{ +- struct rpisense *rpisense = i2c_get_clientdata(i2c); +- +- platform_device_unregister(rpisense->joystick.pdev); +-} +- +-struct rpisense *rpisense_get_dev(void) +-{ +- return rpisense; +-} +-EXPORT_SYMBOL_GPL(rpisense_get_dev); +- +-s32 rpisense_reg_read(struct rpisense *rpisense, int reg) +-{ +- int ret = i2c_smbus_read_byte_data(rpisense->i2c_client, reg); +- +- if (ret < 0) +- dev_err(rpisense->dev, "Read from reg %d failed\n", reg); +- /* Due to the BCM270x I2C clock stretching bug, some values +- * may have MSB set. Clear it to avoid incorrect values. +- * */ +- return ret & 0x7F; +-} +-EXPORT_SYMBOL_GPL(rpisense_reg_read); +- +-int rpisense_block_write(struct rpisense *rpisense, const char *buf, int count) +-{ +- int ret = i2c_master_send(rpisense->i2c_client, buf, count); +- +- if (ret < 0) +- dev_err(rpisense->dev, "Block write failed\n"); +- return ret; +-} +-EXPORT_SYMBOL_GPL(rpisense_block_write); +- +-static const struct i2c_device_id rpisense_i2c_id[] = { +- { "rpi-sense", 0 }, +- { } +-}; +-MODULE_DEVICE_TABLE(i2c, rpisense_i2c_id); +- +-#ifdef CONFIG_OF +-static const struct of_device_id rpisense_core_id[] = { +- { .compatible = "rpi,rpi-sense" }, +- { }, +-}; +-MODULE_DEVICE_TABLE(of, rpisense_core_id); +-#endif +- +- +-static struct i2c_driver rpisense_driver = { +- .driver = { +- .name = "rpi-sense", +- .owner = THIS_MODULE, +- }, +- .probe = rpisense_probe, +- .remove = rpisense_remove, +- .id_table = rpisense_i2c_id, +-}; +- +-module_i2c_driver(rpisense_driver); +- +-MODULE_DESCRIPTION("Raspberry Pi Sense HAT core driver"); +-MODULE_AUTHOR("Serge Schneider "); +-MODULE_LICENSE("GPL"); +- +--- a/drivers/video/fbdev/Kconfig ++++ b/drivers/video/fbdev/Kconfig +@@ -1967,8 +1967,8 @@ config FB_SM712 + + config FB_RPISENSE + tristate "Raspberry Pi Sense HAT framebuffer" +- depends on FB +- select MFD_RPISENSE_CORE ++ depends on FB && I2C ++ select MFD_SIMPLE_MFD_I2C + select FB_SYS_FOPS + select FB_SYS_FILLRECT + select FB_SYS_COPYAREA +--- a/drivers/video/fbdev/rpisense-fb.c ++++ b/drivers/video/fbdev/rpisense-fb.c +@@ -23,16 +23,14 @@ + #include + #include + #include ++#include + + #include +-#include + + static bool lowlight; + module_param(lowlight, bool, 0); + MODULE_PARM_DESC(lowlight, "Reduce LED matrix brightness to one third"); + +-static struct rpisense *rpisense; +- + struct rpisense_fb_param { + char __iomem *vmem; + u8 *vmem_work; +@@ -116,26 +114,26 @@ static void rpisense_fb_imageblit(struct + } + + static void rpisense_fb_deferred_io(struct fb_info *info, +- struct list_head *pagelist) ++ struct list_head *pagelist) + { + int i; + int j; + u8 *vmem_work = rpisense_fb_param.vmem_work; + u16 *mem = (u16 *)rpisense_fb_param.vmem; + u8 *gamma = rpisense_fb_param.gamma; ++ struct rpisense_fb *rpisense_fb = info->par; + +- vmem_work[0] = 0; + for (j = 0; j < 8; j++) { + for (i = 0; i < 8; i++) { +- vmem_work[(j * 24) + i + 1] = ++ vmem_work[(j * 24) + i] = + gamma[(mem[(j * 8) + i] >> 11) & 0x1F]; +- vmem_work[(j * 24) + (i + 8) + 1] = ++ vmem_work[(j * 24) + (i + 8)] = + gamma[(mem[(j * 8) + i] >> 6) & 0x1F]; +- vmem_work[(j * 24) + (i + 16) + 1] = ++ vmem_work[(j * 24) + (i + 16)] = + gamma[(mem[(j * 8) + i]) & 0x1F]; + } + } +- rpisense_block_write(rpisense, vmem_work, 193); ++ regmap_bulk_write(rpisense_fb->regmap, 0, vmem_work, 192); + } + + static struct fb_deferred_io rpisense_fb_defio = { +@@ -200,8 +198,22 @@ static int rpisense_fb_probe(struct plat + int ret = -ENOMEM; + struct rpisense_fb *rpisense_fb; + +- rpisense = rpisense_get_dev(); +- rpisense_fb = &rpisense->framebuffer; ++ info = framebuffer_alloc(sizeof(*rpisense_fb), &pdev->dev); ++ if (!info) { ++ dev_err(&pdev->dev, "Could not allocate framebuffer.\n"); ++ goto err_malloc; ++ } ++ ++ rpisense_fb = info->par; ++ platform_set_drvdata(pdev, rpisense_fb); ++ ++ rpisense_fb->pdev = pdev; ++ rpisense_fb->regmap = dev_get_regmap(pdev->dev.parent, NULL); ++ if (!rpisense_fb->regmap) { ++ dev_err(&pdev->dev, ++ "unable to get sensehat regmap"); ++ return -ENODEV; ++ } + + rpisense_fb_param.vmem = vzalloc(rpisense_fb_param.vmemsize); + if (!rpisense_fb_param.vmem) +@@ -211,12 +223,6 @@ static int rpisense_fb_probe(struct plat + if (!rpisense_fb_param.vmem_work) + goto err_malloc; + +- info = framebuffer_alloc(0, &pdev->dev); +- if (!info) { +- dev_err(&pdev->dev, "Could not allocate framebuffer.\n"); +- goto err_malloc; +- } +- rpisense_fb->info = info; + + rpisense_fb_fix.smem_start = (unsigned long)rpisense_fb_param.vmem; + rpisense_fb_fix.smem_len = rpisense_fb_param.vmemsize; +@@ -253,7 +259,7 @@ err_malloc: + + static int rpisense_fb_remove(struct platform_device *pdev) + { +- struct rpisense_fb *rpisense_fb = &rpisense->framebuffer; ++ struct rpisense_fb *rpisense_fb = platform_get_drvdata(pdev); + struct fb_info *info = rpisense_fb->info; + + if (info) { +@@ -266,19 +272,11 @@ static int rpisense_fb_remove(struct pla + return 0; + } + +-#ifdef CONFIG_OF + static const struct of_device_id rpisense_fb_id[] = { +- { .compatible = "rpi,rpi-sense-fb" }, ++ { .compatible = "raspberrypi,rpi-sense-fb" }, + { }, + }; + MODULE_DEVICE_TABLE(of, rpisense_fb_id); +-#endif +- +-static struct platform_device_id rpisense_fb_device_id[] = { +- { .name = "rpi-sense-fb" }, +- { }, +-}; +-MODULE_DEVICE_TABLE(platform, rpisense_fb_device_id); + + static struct platform_driver rpisense_fb_driver = { + .probe = rpisense_fb_probe, +@@ -286,6 +284,7 @@ static struct platform_driver rpisense_f + .driver = { + .name = "rpi-sense-fb", + .owner = THIS_MODULE, ++ .of_match_table = rpisense_fb_id, + }, + }; + +--- a/include/linux/mfd/rpisense/core.h ++++ /dev/null +@@ -1,47 +0,0 @@ +-/* +- * Raspberry Pi Sense HAT core driver +- * http://raspberrypi.org +- * +- * Copyright (C) 2015 Raspberry Pi +- * +- * Author: Serge Schneider +- * +- * This program is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License as published by the +- * Free Software Foundation; either version 2 of the License, or (at your +- * option) any later version. +- * +- */ +- +-#ifndef __LINUX_MFD_RPISENSE_CORE_H_ +-#define __LINUX_MFD_RPISENSE_CORE_H_ +- +-#include +-#include +- +-/* +- * Register values. +- */ +-#define RPISENSE_FB 0x00 +-#define RPISENSE_WAI 0xF0 +-#define RPISENSE_VER 0xF1 +-#define RPISENSE_KEYS 0xF2 +-#define RPISENSE_EE_WP 0xF3 +- +-#define RPISENSE_ID 's' +- +-struct rpisense { +- struct device *dev; +- struct i2c_client *i2c_client; +- +- /* Client devices */ +- struct rpisense_js joystick; +- struct rpisense_fb framebuffer; +-}; +- +-struct rpisense *rpisense_get_dev(void); +-s32 rpisense_reg_read(struct rpisense *rpisense, int reg); +-int rpisense_reg_write(struct rpisense *rpisense, int reg, u16 val); +-int rpisense_block_write(struct rpisense *rpisense, const char *buf, int count); +- +-#endif +--- a/include/linux/mfd/rpisense/framebuffer.h ++++ b/include/linux/mfd/rpisense/framebuffer.h +@@ -16,6 +16,8 @@ + #ifndef __LINUX_RPISENSE_FB_H_ + #define __LINUX_RPISENSE_FB_H_ + ++#include ++ + #define SENSEFB_FBIO_IOC_MAGIC 0xF1 + + #define SENSEFB_FBIOGET_GAMMA _IO(SENSEFB_FBIO_IOC_MAGIC, 0) +@@ -25,8 +27,9 @@ + struct rpisense; + + struct rpisense_fb { +- struct platform_device *pdev; + struct fb_info *info; ++ struct platform_device *pdev; ++ struct regmap *regmap; + }; + + #endif diff --git a/target/linux/bcm27xx/patches-6.6/950-1315-Reapply-Input-sensehat-joystick-Revert-to-downstream.patch b/target/linux/bcm27xx/patches-6.6/950-1315-Reapply-Input-sensehat-joystick-Revert-to-downstream.patch new file mode 100644 index 00000000000..87d84a9fac3 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1315-Reapply-Input-sensehat-joystick-Revert-to-downstream.patch @@ -0,0 +1,22 @@ +From 3a7ab92b9be0f8849941ed66049b9c3744cbd5aa Mon Sep 17 00:00:00 2001 +From: Dom Cobley +Date: Thu, 10 Oct 2024 17:18:57 +0100 +Subject: [PATCH 1315/1350] Reapply "Input: sensehat-joystick : Revert to + downstream keymap" + +This reverts commit bdb00151ff537c119cea7125e665a9bee1f76c58. +--- + drivers/input/joystick/sensehat-joystick.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/input/joystick/sensehat-joystick.c ++++ b/drivers/input/joystick/sensehat-joystick.c +@@ -28,7 +28,7 @@ struct sensehat_joystick { + }; + + static const unsigned int keymap[] = { +- BTN_DPAD_DOWN, BTN_DPAD_RIGHT, BTN_DPAD_UP, BTN_SELECT, BTN_DPAD_LEFT, ++ KEY_DOWN, KEY_RIGHT, KEY_UP, KEY_ENTER, KEY_LEFT + }; + + static irqreturn_t sensehat_joystick_report(int irq, void *cookie) diff --git a/target/linux/bcm27xx/patches-6.6/950-1316-Reapply-dtoverlays-Add-Sense-Hat-to-hat_map.patch b/target/linux/bcm27xx/patches-6.6/950-1316-Reapply-dtoverlays-Add-Sense-Hat-to-hat_map.patch new file mode 100644 index 00000000000..c4a2ee2ecea --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1316-Reapply-dtoverlays-Add-Sense-Hat-to-hat_map.patch @@ -0,0 +1,27 @@ +From 2132f8aad4e978a9789a84f667567ce2bc93cb3c Mon Sep 17 00:00:00 2001 +From: Dom Cobley +Date: Thu, 10 Oct 2024 17:19:06 +0100 +Subject: [PATCH 1316/1350] Reapply "dtoverlays: Add Sense Hat to hat_map" + +This reverts commit 14fc8b7994220e9b3d85c07b53c5704d5e082944. +--- + arch/arm/boot/dts/overlays/hat_map.dts | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/arch/arm/boot/dts/overlays/hat_map.dts ++++ b/arch/arm/boot/dts/overlays/hat_map.dts +@@ -95,4 +95,14 @@ + uuid = [ 1c955808 681f 4bbc a2ef b7ea47cd388e ]; + overlay = "recalboxrgbdual"; + }; ++ ++ sensehat-v1 { ++ uuid = [ 5d960035 8e87 428f 95d8 59852d697754 ]; ++ overlay = "rpi-sense"; ++ }; ++ ++ sensehat-v2 { ++ uuid = [ 1aa9c428 72eb 48da 9306 8c3706ed3653 ]; ++ overlay = "rpi-sense-v2"; ++ }; + }; diff --git a/target/linux/bcm27xx/patches-6.6/950-1317-overlays-hat_map-Add-Sense-and-Hailo-AI-HATs.patch b/target/linux/bcm27xx/patches-6.6/950-1317-overlays-hat_map-Add-Sense-and-Hailo-AI-HATs.patch new file mode 100644 index 00000000000..041447eaaac --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1317-overlays-hat_map-Add-Sense-and-Hailo-AI-HATs.patch @@ -0,0 +1,54 @@ +From e53eefbc711622f0702e887f88d69f867aa0bf1a Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 1 Oct 2024 12:14:57 +0100 +Subject: [PATCH 1317/1350] overlays: hat_map: Add Sense and Hailo AI HATs + +Add mappings to overlays for the Sense HATs and the Hailo AI HATs. Note +that mapping by product names (and not UUIDs) as used here requires an +updated firmware. + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/overlays/hat_map.dts | 20 ++++++++++++++++++-- + 1 file changed, 18 insertions(+), 2 deletions(-) + +--- a/arch/arm/boot/dts/overlays/hat_map.dts ++++ b/arch/arm/boot/dts/overlays/hat_map.dts +@@ -1,6 +1,18 @@ + /dts-v1/; + + / { ++ hailo-8 { ++ product = "Raspberry Pi AI Hat, Model Hailo-8"; ++ vendor = "Hailo Technologies"; ++ overlay = "none,pciex1,pciex1_gen=3"; ++ }; ++ ++ hailo-8l { ++ product = "Raspberry Pi AI Hat, Model Hailo-8L"; ++ vendor = "Hailo Technologies"; ++ overlay = "none,pciex1,pciex1_gen=3"; ++ }; ++ + hifiberry-amp100-1 { + uuid = [ 5eb863b8 12f9 41ad 978f 4cee1b3eca62 ]; + overlay = "hifiberry-amp100"; +@@ -97,12 +109,16 @@ + }; + + sensehat-v1 { +- uuid = [ 5d960035 8e87 428f 95d8 59852d697754 ]; ++ product = "Sense HAT"; ++ vendor = "Raspberry Pi"; ++ pver = < 0x0001 >; + overlay = "rpi-sense"; + }; + + sensehat-v2 { +- uuid = [ 1aa9c428 72eb 48da 9306 8c3706ed3653 ]; ++ product = "Sense HAT"; ++ vendor = "Raspberry Pi"; ++ pver = < 0x0002 >; + overlay = "rpi-sense-v2"; + }; + }; diff --git a/target/linux/bcm27xx/patches-6.6/950-1318-drivers-media-imx500-Enable-LS-correction.patch b/target/linux/bcm27xx/patches-6.6/950-1318-drivers-media-imx500-Enable-LS-correction.patch new file mode 100644 index 00000000000..6d3233c80b2 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1318-drivers-media-imx500-Enable-LS-correction.patch @@ -0,0 +1,408 @@ +From e2cafea49115af21f84e315e228121ec10dd4cb3 Mon Sep 17 00:00:00 2001 +From: Naushir Patuck +Date: Fri, 11 Oct 2024 12:32:46 +0100 +Subject: [PATCH 1318/1350] drivers: media: imx500: Enable LS correction + +This correction is calibrated to approx 5000K. + +Signed-off-by: Naushir Patuck +--- + drivers/media/i2c/imx500.c | 387 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 387 insertions(+) + +--- a/drivers/media/i2c/imx500.c ++++ b/drivers/media/i2c/imx500.c +@@ -887,6 +887,393 @@ static const struct cci_reg_sequence dnn + { CCI_REG32(0xd950), 0xfb00f7 }, + { CCI_REG16(0xd954), 0xff }, + { CCI_REG8(0xd826), 1 }, ++ /* LSC */ ++ { CCI_REG32(0xe000), 0x2e502a0 }, ++ { CCI_REG32(0xe004), 0x2c80283 }, ++ { CCI_REG32(0xe008), 0x2700233 }, ++ { CCI_REG32(0xe00c), 0x22d01f6 }, ++ { CCI_REG32(0xe010), 0x1f401c3 }, ++ { CCI_REG32(0xe014), 0x1c5019c }, ++ { CCI_REG32(0xe018), 0x1bb0192 }, ++ { CCI_REG32(0xe01c), 0x1ba0192 }, ++ { CCI_REG32(0xe020), 0x1b90192 }, ++ { CCI_REG32(0xe024), 0x1ba0192 }, ++ { CCI_REG32(0xe028), 0x1ca019f }, ++ { CCI_REG32(0xe02c), 0x1fb01c8 }, ++ { CCI_REG32(0xe030), 0x23601fb }, ++ { CCI_REG32(0xe034), 0x27a0239 }, ++ { CCI_REG32(0xe038), 0x2d5028a }, ++ { CCI_REG32(0xe03c), 0x2f302a8 }, ++ { CCI_REG32(0xe040), 0x2c60283 }, ++ { CCI_REG32(0xe044), 0x27c0240 }, ++ { CCI_REG32(0xe048), 0x22d01f6 }, ++ { CCI_REG32(0xe04c), 0x1fd01cd }, ++ { CCI_REG32(0xe050), 0x1c4019c }, ++ { CCI_REG32(0xe054), 0x19c017b }, ++ { CCI_REG32(0xe058), 0x1810165 }, ++ { CCI_REG32(0xe05c), 0x175015c }, ++ { CCI_REG32(0xe060), 0x175015c }, ++ { CCI_REG32(0xe064), 0x1840167 }, ++ { CCI_REG32(0xe068), 0x1a0017e }, ++ { CCI_REG32(0xe06c), 0x1cc01a1 }, ++ { CCI_REG32(0xe070), 0x20501d1 }, ++ { CCI_REG32(0xe074), 0x23601fc }, ++ { CCI_REG32(0xe078), 0x2890246 }, ++ { CCI_REG32(0xe07c), 0x2d3028a }, ++ { CCI_REG32(0xe080), 0x2800243 }, ++ { CCI_REG32(0xe084), 0x245020e }, ++ { CCI_REG32(0xe088), 0x1ff01ce }, ++ { CCI_REG32(0xe08c), 0x1c4019c }, ++ { CCI_REG32(0xe090), 0x19a017b }, ++ { CCI_REG32(0xe094), 0x1650150 }, ++ { CCI_REG32(0xe098), 0x14a013a }, ++ { CCI_REG32(0xe09c), 0x13f0131 }, ++ { CCI_REG32(0xe0a0), 0x1400131 }, ++ { CCI_REG32(0xe0a4), 0x14d013c }, ++ { CCI_REG32(0xe0a8), 0x16a0154 }, ++ { CCI_REG32(0xe0ac), 0x1a1017e }, ++ { CCI_REG32(0xe0b0), 0x1cc01a1 }, ++ { CCI_REG32(0xe0b4), 0x20801d3 }, ++ { CCI_REG32(0xe0b8), 0x2510214 }, ++ { CCI_REG32(0xe0bc), 0x28b0249 }, ++ { CCI_REG32(0xe0c0), 0x2640229 }, ++ { CCI_REG32(0xe0c4), 0x22101ed }, ++ { CCI_REG32(0xe0c8), 0x1dc01b0 }, ++ { CCI_REG32(0xe0cc), 0x19c017c }, ++ { CCI_REG32(0xe0d0), 0x1650150 }, ++ { CCI_REG32(0xe0d4), 0x148013a }, ++ { CCI_REG32(0xe0d8), 0x123011c }, ++ { CCI_REG32(0xe0dc), 0x1190113 }, ++ { CCI_REG32(0xe0e0), 0x1190113 }, ++ { CCI_REG32(0xe0e4), 0x1280120 }, ++ { CCI_REG32(0xe0e8), 0x14c013c }, ++ { CCI_REG32(0xe0ec), 0x16b0154 }, ++ { CCI_REG32(0xe0f0), 0x1a30181 }, ++ { CCI_REG32(0xe0f4), 0x1e601b6 }, ++ { CCI_REG32(0xe0f8), 0x22c01f3 }, ++ { CCI_REG32(0xe0fc), 0x2700230 }, ++ { CCI_REG32(0xe100), 0x257021d }, ++ { CCI_REG32(0xe104), 0x20901d8 }, ++ { CCI_REG32(0xe108), 0x1c4019d }, ++ { CCI_REG32(0xe10c), 0x1820167 }, ++ { CCI_REG32(0xe110), 0x14b013b }, ++ { CCI_REG32(0xe114), 0x124011c }, ++ { CCI_REG32(0xe118), 0x1170113 }, ++ { CCI_REG32(0xe11c), 0x1010101 }, ++ { CCI_REG32(0xe120), 0x1030102 }, ++ { CCI_REG32(0xe124), 0x1190113 }, ++ { CCI_REG32(0xe128), 0x1280120 }, ++ { CCI_REG32(0xe12c), 0x14f013f }, ++ { CCI_REG32(0xe130), 0x189016c }, ++ { CCI_REG32(0xe134), 0x1ce01a3 }, ++ { CCI_REG32(0xe138), 0x21601df }, ++ { CCI_REG32(0xe13c), 0x2630224 }, ++ { CCI_REG32(0xe140), 0x257021d }, ++ { CCI_REG32(0xe144), 0x20101d0 }, ++ { CCI_REG32(0xe148), 0x1ba0194 }, ++ { CCI_REG32(0xe14c), 0x176015d }, ++ { CCI_REG32(0xe150), 0x13e0132 }, ++ { CCI_REG32(0xe154), 0x1190114 }, ++ { CCI_REG32(0xe158), 0x1010101 }, ++ { CCI_REG32(0xe15c), 0x1000100 }, ++ { CCI_REG32(0xe160), 0x1010100 }, ++ { CCI_REG32(0xe164), 0x1040103 }, ++ { CCI_REG32(0xe168), 0x11d0118 }, ++ { CCI_REG32(0xe16c), 0x1450136 }, ++ { CCI_REG32(0xe170), 0x17d0163 }, ++ { CCI_REG32(0xe174), 0x1c4019a }, ++ { CCI_REG32(0xe178), 0x20d01d6 }, ++ { CCI_REG32(0xe17c), 0x2630224 }, ++ { CCI_REG32(0xe180), 0x257021d }, ++ { CCI_REG32(0xe184), 0x20001d0 }, ++ { CCI_REG32(0xe188), 0x1b90194 }, ++ { CCI_REG32(0xe18c), 0x175015d }, ++ { CCI_REG32(0xe190), 0x13e0132 }, ++ { CCI_REG32(0xe194), 0x1180114 }, ++ { CCI_REG32(0xe198), 0x1040103 }, ++ { CCI_REG32(0xe19c), 0x1000100 }, ++ { CCI_REG32(0xe1a0), 0x1030102 }, ++ { CCI_REG32(0xe1a4), 0x1050103 }, ++ { CCI_REG32(0xe1a8), 0x11d0118 }, ++ { CCI_REG32(0xe1ac), 0x1450136 }, ++ { CCI_REG32(0xe1b0), 0x17d0163 }, ++ { CCI_REG32(0xe1b4), 0x1c4019a }, ++ { CCI_REG32(0xe1b8), 0x20d01d6 }, ++ { CCI_REG32(0xe1bc), 0x2640224 }, ++ { CCI_REG32(0xe1c0), 0x258021f }, ++ { CCI_REG32(0xe1c4), 0x20e01db }, ++ { CCI_REG32(0xe1c8), 0x1c7019f }, ++ { CCI_REG32(0xe1cc), 0x1840169 }, ++ { CCI_REG32(0xe1d0), 0x14d013e }, ++ { CCI_REG32(0xe1d4), 0x1290120 }, ++ { CCI_REG32(0xe1d8), 0x1180114 }, ++ { CCI_REG32(0xe1dc), 0x1050103 }, ++ { CCI_REG32(0xe1e0), 0x1050103 }, ++ { CCI_REG32(0xe1e4), 0x11e0117 }, ++ { CCI_REG32(0xe1e8), 0x12c0123 }, ++ { CCI_REG32(0xe1ec), 0x1530142 }, ++ { CCI_REG32(0xe1f0), 0x18d016f }, ++ { CCI_REG32(0xe1f4), 0x1d201a6 }, ++ { CCI_REG32(0xe1f8), 0x21a01e2 }, ++ { CCI_REG32(0xe1fc), 0x2640225 }, ++ { CCI_REG32(0xe200), 0x269022d }, ++ { CCI_REG32(0xe204), 0x22601f1 }, ++ { CCI_REG32(0xe208), 0x1e101b4 }, ++ { CCI_REG32(0xe20c), 0x1a10181 }, ++ { CCI_REG32(0xe210), 0x16c0156 }, ++ { CCI_REG32(0xe214), 0x14d013e }, ++ { CCI_REG32(0xe218), 0x1290120 }, ++ { CCI_REG32(0xe21c), 0x11f0118 }, ++ { CCI_REG32(0xe220), 0x11f0118 }, ++ { CCI_REG32(0xe224), 0x12b0123 }, ++ { CCI_REG32(0xe228), 0x1530142 }, ++ { CCI_REG32(0xe22c), 0x172015a }, ++ { CCI_REG32(0xe230), 0x1aa0187 }, ++ { CCI_REG32(0xe234), 0x1ec01bb }, ++ { CCI_REG32(0xe238), 0x23301f8 }, ++ { CCI_REG32(0xe23c), 0x2750233 }, ++ { CCI_REG32(0xe240), 0x28b024c }, ++ { CCI_REG32(0xe244), 0x24f0216 }, ++ { CCI_REG32(0xe248), 0x20701d4 }, ++ { CCI_REG32(0xe24c), 0x1ce01a4 }, ++ { CCI_REG32(0xe250), 0x1a10181 }, ++ { CCI_REG32(0xe254), 0x16c0156 }, ++ { CCI_REG32(0xe258), 0x1520141 }, ++ { CCI_REG32(0xe25c), 0x1480138 }, ++ { CCI_REG32(0xe260), 0x1480138 }, ++ { CCI_REG32(0xe264), 0x1550143 }, ++ { CCI_REG32(0xe268), 0x172015a }, ++ { CCI_REG32(0xe26c), 0x1aa0187 }, ++ { CCI_REG32(0xe270), 0x1d701a9 }, ++ { CCI_REG32(0xe274), 0x21201db }, ++ { CCI_REG32(0xe278), 0x25d021d }, ++ { CCI_REG32(0xe27c), 0x2990254 }, ++ { CCI_REG32(0xe280), 0x2d70291 }, ++ { CCI_REG32(0xe284), 0x28c024c }, ++ { CCI_REG32(0xe288), 0x2390201 }, ++ { CCI_REG32(0xe28c), 0x20701d4 }, ++ { CCI_REG32(0xe290), 0x1ce01a4 }, ++ { CCI_REG32(0xe294), 0x1a70184 }, ++ { CCI_REG32(0xe298), 0x18c016e }, ++ { CCI_REG32(0xe29c), 0x1810164 }, ++ { CCI_REG32(0xe2a0), 0x1810164 }, ++ { CCI_REG32(0xe2a4), 0x1900170 }, ++ { CCI_REG32(0xe2a8), 0x1ad0188 }, ++ { CCI_REG32(0xe2ac), 0x1d601a9 }, ++ { CCI_REG32(0xe2b0), 0x21201da }, ++ { CCI_REG32(0xe2b4), 0x2450207 }, ++ { CCI_REG32(0xe2b8), 0x29a0254 }, ++ { CCI_REG32(0xe2bc), 0x2ea029d }, ++ { CCI_REG32(0xe2c0), 0x2f602ae }, ++ { CCI_REG32(0xe2c4), 0x2d80291 }, ++ { CCI_REG32(0xe2c8), 0x280023f }, ++ { CCI_REG32(0xe2cc), 0x2390200 }, ++ { CCI_REG32(0xe2d0), 0x1fe01cc }, ++ { CCI_REG32(0xe2d4), 0x1d201a4 }, ++ { CCI_REG32(0xe2d8), 0x1c6019b }, ++ { CCI_REG32(0xe2dc), 0x1c6019b }, ++ { CCI_REG32(0xe2e0), 0x1c6019b }, ++ { CCI_REG32(0xe2e4), 0x1c8019b }, ++ { CCI_REG32(0xe2e8), 0x1d701a9 }, ++ { CCI_REG32(0xe2ec), 0x20801d1 }, ++ { CCI_REG32(0xe2f0), 0x2450206 }, ++ { CCI_REG32(0xe2f4), 0x28e0248 }, ++ { CCI_REG32(0xe2f8), 0x2ec029d }, ++ { CCI_REG32(0xe2fc), 0x30902b9 }, ++ { CCI_REG32(0xe300), 0x2a002a4 }, ++ { CCI_REG32(0xe304), 0x2830286 }, ++ { CCI_REG32(0xe308), 0x2330234 }, ++ { CCI_REG32(0xe30c), 0x1f601f7 }, ++ { CCI_REG32(0xe310), 0x1c301c4 }, ++ { CCI_REG32(0xe314), 0x19c019c }, ++ { CCI_REG32(0xe318), 0x1920193 }, ++ { CCI_REG32(0xe31c), 0x1920193 }, ++ { CCI_REG32(0xe320), 0x1920192 }, ++ { CCI_REG32(0xe324), 0x1920193 }, ++ { CCI_REG32(0xe328), 0x19f01a1 }, ++ { CCI_REG32(0xe32c), 0x1c801ca }, ++ { CCI_REG32(0xe330), 0x1fb01fe }, ++ { CCI_REG32(0xe334), 0x239023e }, ++ { CCI_REG32(0xe338), 0x28a0292 }, ++ { CCI_REG32(0xe33c), 0x2a802b0 }, ++ { CCI_REG32(0xe340), 0x2830287 }, ++ { CCI_REG32(0xe344), 0x2400242 }, ++ { CCI_REG32(0xe348), 0x1f601f8 }, ++ { CCI_REG32(0xe34c), 0x1cd01ce }, ++ { CCI_REG32(0xe350), 0x19c019d }, ++ { CCI_REG32(0xe354), 0x17b017d }, ++ { CCI_REG32(0xe358), 0x1650166 }, ++ { CCI_REG32(0xe35c), 0x15c015d }, ++ { CCI_REG32(0xe360), 0x15c015d }, ++ { CCI_REG32(0xe364), 0x1670168 }, ++ { CCI_REG32(0xe368), 0x17e0180 }, ++ { CCI_REG32(0xe36c), 0x1a101a3 }, ++ { CCI_REG32(0xe370), 0x1d101d3 }, ++ { CCI_REG32(0xe374), 0x1fc0200 }, ++ { CCI_REG32(0xe378), 0x246024c }, ++ { CCI_REG32(0xe37c), 0x28a0291 }, ++ { CCI_REG32(0xe380), 0x2430245 }, ++ { CCI_REG32(0xe384), 0x20e0211 }, ++ { CCI_REG32(0xe388), 0x1ce01d0 }, ++ { CCI_REG32(0xe38c), 0x19c019e }, ++ { CCI_REG32(0xe390), 0x17b017c }, ++ { CCI_REG32(0xe394), 0x1500152 }, ++ { CCI_REG32(0xe398), 0x13a013c }, ++ { CCI_REG32(0xe39c), 0x1310134 }, ++ { CCI_REG32(0xe3a0), 0x1310134 }, ++ { CCI_REG32(0xe3a4), 0x13c013f }, ++ { CCI_REG32(0xe3a8), 0x1540156 }, ++ { CCI_REG32(0xe3ac), 0x17e0180 }, ++ { CCI_REG32(0xe3b0), 0x1a101a4 }, ++ { CCI_REG32(0xe3b4), 0x1d301d8 }, ++ { CCI_REG32(0xe3b8), 0x2140219 }, ++ { CCI_REG32(0xe3bc), 0x249024e }, ++ { CCI_REG32(0xe3c0), 0x229022b }, ++ { CCI_REG32(0xe3c4), 0x1ed01ef }, ++ { CCI_REG32(0xe3c8), 0x1b001b2 }, ++ { CCI_REG32(0xe3cc), 0x17c017e }, ++ { CCI_REG32(0xe3d0), 0x1500151 }, ++ { CCI_REG32(0xe3d4), 0x13a013c }, ++ { CCI_REG32(0xe3d8), 0x11c011f }, ++ { CCI_REG32(0xe3dc), 0x1130117 }, ++ { CCI_REG32(0xe3e0), 0x1130117 }, ++ { CCI_REG32(0xe3e4), 0x1200123 }, ++ { CCI_REG32(0xe3e8), 0x13c013f }, ++ { CCI_REG32(0xe3ec), 0x1540156 }, ++ { CCI_REG32(0xe3f0), 0x1810183 }, ++ { CCI_REG32(0xe3f4), 0x1b601ba }, ++ { CCI_REG32(0xe3f8), 0x1f301f6 }, ++ { CCI_REG32(0xe3fc), 0x2300234 }, ++ { CCI_REG32(0xe400), 0x21d0221 }, ++ { CCI_REG32(0xe404), 0x1d801db }, ++ { CCI_REG32(0xe408), 0x19d019f }, ++ { CCI_REG32(0xe40c), 0x1670169 }, ++ { CCI_REG32(0xe410), 0x13b013d }, ++ { CCI_REG32(0xe414), 0x11c011f }, ++ { CCI_REG32(0xe418), 0x1130117 }, ++ { CCI_REG32(0xe41c), 0x1010106 }, ++ { CCI_REG32(0xe420), 0x1020108 }, ++ { CCI_REG32(0xe424), 0x1130117 }, ++ { CCI_REG32(0xe428), 0x1200123 }, ++ { CCI_REG32(0xe42c), 0x13f0142 }, ++ { CCI_REG32(0xe430), 0x16c016f }, ++ { CCI_REG32(0xe434), 0x1a301a6 }, ++ { CCI_REG32(0xe438), 0x1df01e2 }, ++ { CCI_REG32(0xe43c), 0x2240228 }, ++ { CCI_REG32(0xe440), 0x21d0220 }, ++ { CCI_REG32(0xe444), 0x1d001d3 }, ++ { CCI_REG32(0xe448), 0x1940196 }, ++ { CCI_REG32(0xe44c), 0x15d0160 }, ++ { CCI_REG32(0xe450), 0x1320135 }, ++ { CCI_REG32(0xe454), 0x1140118 }, ++ { CCI_REG32(0xe458), 0x1010106 }, ++ { CCI_REG32(0xe45c), 0x1000106 }, ++ { CCI_REG32(0xe460), 0x1000106 }, ++ { CCI_REG32(0xe464), 0x1030109 }, ++ { CCI_REG32(0xe468), 0x118011b }, ++ { CCI_REG32(0xe46c), 0x136013a }, ++ { CCI_REG32(0xe470), 0x1630165 }, ++ { CCI_REG32(0xe474), 0x19a019c }, ++ { CCI_REG32(0xe478), 0x1d601d9 }, ++ { CCI_REG32(0xe47c), 0x2240227 }, ++ { CCI_REG32(0xe480), 0x21d0220 }, ++ { CCI_REG32(0xe484), 0x1d001d3 }, ++ { CCI_REG32(0xe488), 0x1940196 }, ++ { CCI_REG32(0xe48c), 0x15d0160 }, ++ { CCI_REG32(0xe490), 0x1320135 }, ++ { CCI_REG32(0xe494), 0x1140118 }, ++ { CCI_REG32(0xe498), 0x1030109 }, ++ { CCI_REG32(0xe49c), 0x1000106 }, ++ { CCI_REG32(0xe4a0), 0x1020108 }, ++ { CCI_REG32(0xe4a4), 0x1030109 }, ++ { CCI_REG32(0xe4a8), 0x118011b }, ++ { CCI_REG32(0xe4ac), 0x1360139 }, ++ { CCI_REG32(0xe4b0), 0x1630165 }, ++ { CCI_REG32(0xe4b4), 0x19a019c }, ++ { CCI_REG32(0xe4b8), 0x1d601d9 }, ++ { CCI_REG32(0xe4bc), 0x2240227 }, ++ { CCI_REG32(0xe4c0), 0x21f0221 }, ++ { CCI_REG32(0xe4c4), 0x1db01de }, ++ { CCI_REG32(0xe4c8), 0x19f01a2 }, ++ { CCI_REG32(0xe4cc), 0x169016c }, ++ { CCI_REG32(0xe4d0), 0x13e0141 }, ++ { CCI_REG32(0xe4d4), 0x1200124 }, ++ { CCI_REG32(0xe4d8), 0x1140119 }, ++ { CCI_REG32(0xe4dc), 0x1030109 }, ++ { CCI_REG32(0xe4e0), 0x1030109 }, ++ { CCI_REG32(0xe4e4), 0x117011c }, ++ { CCI_REG32(0xe4e8), 0x1230126 }, ++ { CCI_REG32(0xe4ec), 0x1420145 }, ++ { CCI_REG32(0xe4f0), 0x16f0171 }, ++ { CCI_REG32(0xe4f4), 0x1a601a8 }, ++ { CCI_REG32(0xe4f8), 0x1e201e4 }, ++ { CCI_REG32(0xe4fc), 0x2250227 }, ++ { CCI_REG32(0xe500), 0x22d0231 }, ++ { CCI_REG32(0xe504), 0x1f101f4 }, ++ { CCI_REG32(0xe508), 0x1b401b7 }, ++ { CCI_REG32(0xe50c), 0x1810183 }, ++ { CCI_REG32(0xe510), 0x1560159 }, ++ { CCI_REG32(0xe514), 0x13e0141 }, ++ { CCI_REG32(0xe518), 0x1200124 }, ++ { CCI_REG32(0xe51c), 0x118011c }, ++ { CCI_REG32(0xe520), 0x118011c }, ++ { CCI_REG32(0xe524), 0x1230126 }, ++ { CCI_REG32(0xe528), 0x1420145 }, ++ { CCI_REG32(0xe52c), 0x15a015c }, ++ { CCI_REG32(0xe530), 0x1870188 }, ++ { CCI_REG32(0xe534), 0x1bb01bd }, ++ { CCI_REG32(0xe538), 0x1f801fb }, ++ { CCI_REG32(0xe53c), 0x2330236 }, ++ { CCI_REG32(0xe540), 0x24c0250 }, ++ { CCI_REG32(0xe544), 0x2160219 }, ++ { CCI_REG32(0xe548), 0x1d401d7 }, ++ { CCI_REG32(0xe54c), 0x1a401a6 }, ++ { CCI_REG32(0xe550), 0x1810183 }, ++ { CCI_REG32(0xe554), 0x1560158 }, ++ { CCI_REG32(0xe558), 0x1410144 }, ++ { CCI_REG32(0xe55c), 0x138013b }, ++ { CCI_REG32(0xe560), 0x138013b }, ++ { CCI_REG32(0xe564), 0x1430146 }, ++ { CCI_REG32(0xe568), 0x15a015c }, ++ { CCI_REG32(0xe56c), 0x1870188 }, ++ { CCI_REG32(0xe570), 0x1a901ab }, ++ { CCI_REG32(0xe574), 0x1db01dd }, ++ { CCI_REG32(0xe578), 0x21d0221 }, ++ { CCI_REG32(0xe57c), 0x2540259 }, ++ { CCI_REG32(0xe580), 0x2910296 }, ++ { CCI_REG32(0xe584), 0x24c0251 }, ++ { CCI_REG32(0xe588), 0x2010204 }, ++ { CCI_REG32(0xe58c), 0x1d401d6 }, ++ { CCI_REG32(0xe590), 0x1a401a5 }, ++ { CCI_REG32(0xe594), 0x1840186 }, ++ { CCI_REG32(0xe598), 0x16e0170 }, ++ { CCI_REG32(0xe59c), 0x1640167 }, ++ { CCI_REG32(0xe5a0), 0x1640167 }, ++ { CCI_REG32(0xe5a4), 0x1700173 }, ++ { CCI_REG32(0xe5a8), 0x188018a }, ++ { CCI_REG32(0xe5ac), 0x1a901ab }, ++ { CCI_REG32(0xe5b0), 0x1da01dd }, ++ { CCI_REG32(0xe5b4), 0x207020a }, ++ { CCI_REG32(0xe5b8), 0x2540259 }, ++ { CCI_REG32(0xe5bc), 0x29d02a3 }, ++ { CCI_REG32(0xe5c0), 0x2ae02b4 }, ++ { CCI_REG32(0xe5c4), 0x2910297 }, ++ { CCI_REG32(0xe5c8), 0x23f0243 }, ++ { CCI_REG32(0xe5cc), 0x2000201 }, ++ { CCI_REG32(0xe5d0), 0x1cc01cd }, ++ { CCI_REG32(0xe5d4), 0x1a401a6 }, ++ { CCI_REG32(0xe5d8), 0x19b019d }, ++ { CCI_REG32(0xe5dc), 0x19b019d }, ++ { CCI_REG32(0xe5e0), 0x19b019d }, ++ { CCI_REG32(0xe5e4), 0x19b019e }, ++ { CCI_REG32(0xe5e8), 0x1a901ab }, ++ { CCI_REG32(0xe5ec), 0x1d101d3 }, ++ { CCI_REG32(0xe5f0), 0x2060209 }, ++ { CCI_REG32(0xe5f4), 0x248024b }, ++ { CCI_REG32(0xe5f8), 0x29d02a3 }, ++ { CCI_REG32(0xe5fc), 0x2b902c0 }, ++ { CCI_REG8(0xd822), 0x01 }, ++ { CCI_REG8(0xd823), 0x0f }, + }; + + /* Mode configs */ diff --git a/target/linux/bcm27xx/patches-6.6/950-1319-dts-bcm2712-rpi-500-Add-USER_LED-GPIO-name.patch b/target/linux/bcm27xx/patches-6.6/950-1319-dts-bcm2712-rpi-500-Add-USER_LED-GPIO-name.patch new file mode 100644 index 00000000000..0dabf4bf022 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1319-dts-bcm2712-rpi-500-Add-USER_LED-GPIO-name.patch @@ -0,0 +1,23 @@ +From 0985b32279d47e7ea01152233d26eedcdf721d09 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Fri, 11 Oct 2024 14:24:51 +0100 +Subject: [PATCH 1319/1350] dts: bcm2712-rpi-500: Add USER_LED GPIO name + +The USER_LED signal was missing from the initial DTS. + +Signed-off-by: Phil Elwell +--- + arch/arm64/boot/dts/broadcom/bcm2712-rpi-500.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-500.dts ++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-500.dts +@@ -35,7 +35,7 @@ + "PWR_GPIO", // GPIO_020 + "KEYB_RUN", // GPIO_021 + "-", // GPIO_022 +- "-", // GPIO_023 ++ "USER_LED", // GPIO_023 + "BT_RTS", // GPIO_024 + "BT_CTS", // GPIO_025 + "BT_TXD", // GPIO_026 diff --git a/target/linux/bcm27xx/patches-6.6/950-1321-dtoverlays-Fix-up-imx500-overlays-to-have-unique-clo.patch b/target/linux/bcm27xx/patches-6.6/950-1321-dtoverlays-Fix-up-imx500-overlays-to-have-unique-clo.patch new file mode 100644 index 00000000000..b8e67c649fd --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1321-dtoverlays-Fix-up-imx500-overlays-to-have-unique-clo.patch @@ -0,0 +1,86 @@ +From 239df148741e35d5b54749a624f96dfcacc7c57e Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 14 Oct 2024 15:37:57 +0100 +Subject: [PATCH 1321/1350] dtoverlays: Fix up imx500 overlays to have unique + clock nodes + +The overlay was creating DT nodes /clocks/clk-aicam and +/clocks/clk-aicam-gated for both cam0 and cam1, which resulted +in one failing. + +The clock infrastructure creates the clock name from the node name +without any @N reg extension, so we can't just use that. The nodes +therefore have to be renamed. + +Signed-off-by: Dave Stevenson +--- + arch/arm/boot/dts/overlays/imx500-overlay.dts | 10 ++++++---- + arch/arm/boot/dts/overlays/imx500-pi5-overlay.dts | 10 ++++++---- + 2 files changed, 12 insertions(+), 8 deletions(-) + +--- a/arch/arm/boot/dts/overlays/imx500-overlay.dts ++++ b/arch/arm/boot/dts/overlays/imx500-overlay.dts +@@ -72,16 +72,16 @@ + }; + }; + +- clocks_frag: fragment@104 { ++ fragment@104 { + target-path = "/clocks"; + __overlay__ { +- clk_aicam: clk-aicam { ++ clk_aicam: clk-aicam1 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + }; + +- clk_aicam_gated: clk-aicam-gated { ++ clk_aicam_gated: clk-aicam-gated1 { + compatible = "gpio-gate-clock"; + clocks = <&clk_aicam>; + #clock-cells = <0>; +@@ -98,7 +98,9 @@ + <&csi_frag>, "target:0=",<&csi0>, + <&spi_bridge>, "power-supply:0=",<&cam0_reg>, + <®_frag>, "target:0=",<&cam0_reg>, +- <&cam_node>, "VANA-supply:0=",<&cam0_reg>; ++ <&cam_node>, "VANA-supply:0=",<&cam0_reg>, ++ <&clk_aicam>,"name=clk-aicam0", ++ <&clk_aicam_gated>,"name=clk-aicam-gated0"; + bypass-cache = <&spi_bridge>,"bypass-cache?"; + }; + }; +--- a/arch/arm/boot/dts/overlays/imx500-pi5-overlay.dts ++++ b/arch/arm/boot/dts/overlays/imx500-pi5-overlay.dts +@@ -75,16 +75,16 @@ + }; + }; + +- clocks_frag: fragment@104 { ++ fragment@104 { + target-path = "/clocks"; + __overlay__ { +- clk_aicam: clk-aicam { ++ clk_aicam: clk-aicam1 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + }; + +- clk_aicam_gated: clk-aicam-gated { ++ clk_aicam_gated: clk-aicam-gated1 { + compatible = "gpio-gate-clock"; + clocks = <&clk_aicam>; + #clock-cells = <0>; +@@ -103,7 +103,9 @@ + <&spi_frag_overlay>, "fast_xfer-gpios:16=35", // CD0_IO1_MICDAT0 (clock) + <&spi_bridge>, "power-supply:0=",<&cam0_reg>, + <®_frag>, "target:0=",<&cam0_reg>, +- <&cam_node>, "VANA-supply:0=",<&cam0_reg>; ++ <&cam_node>, "VANA-supply:0=",<&cam0_reg>, ++ <&clk_aicam>,"name=clk-aicam0", ++ <&clk_aicam_gated>,"name=clk-aicam-gated0"; + bypass-cache = <&spi_bridge>,"bypass-cache?"; + }; + }; diff --git a/target/linux/bcm27xx/patches-6.6/950-1322-dtoverlays-Add-an-overlay-for-Waveshare-s-800x480-4..patch b/target/linux/bcm27xx/patches-6.6/950-1322-dtoverlays-Add-an-overlay-for-Waveshare-s-800x480-4..patch new file mode 100644 index 00000000000..4a667981014 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1322-dtoverlays-Add-an-overlay-for-Waveshare-s-800x480-4..patch @@ -0,0 +1,177 @@ +From 6f2d1b4c3132206de40247b604638a51277131fb Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 14 Oct 2024 18:53:43 +0100 +Subject: [PATCH 1322/1350] dtoverlays: Add an overlay for Waveshare's 800x480 + 4.3" DSI screen + +It tried to be a clone of the Pi 7" display, but isn't, and gives +corrupt images with the current timings. + +Add a new overlay for it. + +Signed-off-by: Dave Stevenson +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 17 +++ + .../vc4-kms-dsi-waveshare-800x480-overlay.dts | 119 ++++++++++++++++++ + 3 files changed, 137 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/vc4-kms-dsi-waveshare-800x480-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -319,6 +319,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + vc4-kms-dsi-ili9881-7inch.dtbo \ + vc4-kms-dsi-lt070me05000.dtbo \ + vc4-kms-dsi-lt070me05000-v2.dtbo \ ++ vc4-kms-dsi-waveshare-800x480.dtbo \ + vc4-kms-dsi-waveshare-panel.dtbo \ + vc4-kms-kippah-7inch.dtbo \ + vc4-kms-v3d.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -5248,6 +5248,23 @@ Load: dtoverlay=vc4-kms-dsi-lt070me050 + Params: + + ++Name: vc4-kms-dsi-waveshare-800x480 ++Info: Enable the Waveshare 4.3" 800x480 DSI screen. ++ It tries to look like the Pi 7" display, but won't accept some of the ++ timings. ++ Includes the edt-ft5406 for the touchscreen element. ++ Requires vc4-kms-v3d to be loaded. ++Load: dtoverlay=vc4-kms-dsi-waveshare-800x480,= ++Params: sizex Touchscreen size x (default 800) ++ sizey Touchscreen size y (default 480) ++ invx Touchscreen inverted x axis ++ invy Touchscreen inverted y axis ++ swapxy Touchscreen swapped x y axis ++ disable_touch Disables the touch screen overlay driver ++ dsi0 Use DSI0 and i2c_csi_dsi0 (rather than ++ the default DSI1 and i2c_csi_dsi). ++ ++ + Name: vc4-kms-dsi-waveshare-panel + Info: Enable a Waveshare DSI touchscreen + Includes the Goodix driver for the touchscreen element. +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/vc4-kms-dsi-waveshare-800x480-overlay.dts +@@ -0,0 +1,119 @@ ++/* ++ * Device Tree overlay for Waveshare 4.3" 800x480 panel. ++ * It tries to look like a Pi 7" panel, but fails with some of the timing ++ * options. ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++#include "edt-ft5406.dtsi" ++ ++/ { ++ /* No compatible as it will have come from edt-ft5406.dtsi */ ++ ++ dsi_frag: fragment@0 { ++ target = <&dsi1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ port { ++ dsi_out: endpoint { ++ remote-endpoint = <&panel_dsi_port>; ++ }; ++ }; ++ ++ panel: panel-dsi-generic@0 { ++ // See panel-dsi.yaml binding ++ compatible = "waveshare,4-3-inch-dsi","panel-dsi"; ++ reg = <0>; ++ power-supply = <®_display>; ++ backlight = <®_display>; ++ dsi-color-format = "RGB888"; ++ mode = "MODE_VIDEO"; ++ width-mm = <0>; ++ height-mm = <0>; ++ ++ port { ++ panel_dsi_port: endpoint { ++ data-lanes = <1>; ++ remote-endpoint = <&dsi_out>; ++ }; ++ }; ++ ++ timing: panel-timing { ++ clock-frequency = <27777000>; ++ hactive = <800>; ++ vactive = <480>; ++ hfront-porch = <59>; ++ hsync-len = <2>; ++ hback-porch = <45>; ++ vfront-porch = <7>; ++ vsync-len = <2>; ++ vback-porch = <22>; ++ }; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target-path = "/"; ++ __overlay__ { ++ reg_bridge: reg_bridge@1 { ++ reg = <1>; ++ compatible = "regulator-fixed"; ++ regulator-name = "bridge_reg"; ++ gpio = <®_display 0 0>; ++ vin-supply = <®_display>; ++ enable-active-high; ++ }; ++ }; ++ }; ++ ++ i2c_frag: fragment@2 { ++ target = <&i2c_csi_dsi>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ reg_display: reg_display@45 { ++ compatible = "raspberrypi,7inch-touchscreen-panel-regulator"; ++ reg = <0x45>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ }; ++ }; ++ }; ++ ++ fragment@3 { ++ target = <&i2c0if>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@4 { ++ target = <&i2c0mux>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ fragment@5 { ++ target = <&ft5406>; ++ __overlay__ { ++ vcc-supply = <®_display>; ++ reset-gpio = <®_display 1 1>; ++ }; ++ }; ++ ++ __overrides__ { ++ dsi0 = <&dsi_frag>, "target:0=",<&dsi0>, ++ <&i2c_frag>, "target:0=",<&i2c_csi_dsi0>, ++ <&ts_i2c_frag>, "target:0=",<&i2c_csi_dsi0>, ++ <®_bridge>, "reg:0=0", ++ <®_bridge>, "regulator-name=bridge_reg_0"; ++ disable_touch = <&ft5406>, "status=disabled"; ++ }; ++}; diff --git a/target/linux/bcm27xx/patches-6.6/950-1323-drm-vc4-Remove-request-for-min-clocks-when-hdmi-outp.patch b/target/linux/bcm27xx/patches-6.6/950-1323-drm-vc4-Remove-request-for-min-clocks-when-hdmi-outp.patch new file mode 100644 index 00000000000..9f4cf9d0336 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1323-drm-vc4-Remove-request-for-min-clocks-when-hdmi-outp.patch @@ -0,0 +1,74 @@ +From 18d185166ca00c9280505ad41fbe036efbb52e67 Mon Sep 17 00:00:00 2001 +From: Dom Cobley +Date: Mon, 14 Oct 2024 18:55:00 +0100 +Subject: [PATCH 1323/1350] drm/vc4: Remove request for min clocks when hdmi + output is disabled + +Currently, booting with no hdmi connected has: +pi@pi4:~ $ vcgencmd measure_clock hdmi pixel +frequency(9)=120010256 +frequency(29)=74988280 + +After connecting hdmi we get: +pi@pi4:~ $ vcgencmd measure_clock hdmi pixel +frequency(9)=300005856 +frequency(29)=149989744 + +and that persists after disconnecting hdmi + +I can measure this on a power supply as 10mA@5.2V (52mW). + +We should always remove clk_set_min_rate requests +when we no longer need them. + +Signed-off-by: Dom Cobley +--- + drivers/gpu/drm/vc4/vc4_hdmi.c | 4 ++++ + drivers/gpu/drm/vc4/vc4_hvs.c | 3 +++ + drivers/gpu/drm/vc4/vc4_v3d.c | 2 ++ + 3 files changed, 9 insertions(+) + +--- a/drivers/gpu/drm/vc4/vc4_hdmi.c ++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c +@@ -1224,6 +1224,8 @@ static void vc4_hdmi_encoder_post_crtc_p + if (vc4_hdmi->variant->phy_disable) + vc4_hdmi->variant->phy_disable(vc4_hdmi); + ++ /* we no longer require a minimum clock rate */ ++ clk_set_min_rate(vc4_hdmi->pixel_bvb_clock, 0); + clk_disable_unprepare(vc4_hdmi->pixel_bvb_clock); + clk_disable_unprepare(vc4_hdmi->pixel_clock); + +@@ -3724,6 +3726,8 @@ static int vc4_hdmi_runtime_suspend(stru + struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev); + + clk_disable_unprepare(vc4_hdmi->audio_clock); ++ /* we no longer require a minimum clock rate */ ++ clk_set_min_rate(vc4_hdmi->hsm_clock, 0); + clk_disable_unprepare(vc4_hdmi->hsm_clock); + + return 0; +--- a/drivers/gpu/drm/vc4/vc4_hvs.c ++++ b/drivers/gpu/drm/vc4/vc4_hvs.c +@@ -2308,7 +2308,10 @@ static void vc4_hvs_unbind(struct device + drm_mm_remove_node(node); + drm_mm_takedown(&vc4->hvs->lbm_mm); + ++ /* we no longer require a minimum clock rate */ ++ clk_set_min_rate(hvs->disp_clk, 0); + clk_disable_unprepare(hvs->disp_clk); ++ clk_set_min_rate(hvs->core_clk, 0); + clk_disable_unprepare(hvs->core_clk); + + vc4->hvs = NULL; +--- a/drivers/gpu/drm/vc4/vc4_v3d.c ++++ b/drivers/gpu/drm/vc4/vc4_v3d.c +@@ -376,6 +376,8 @@ static int vc4_v3d_runtime_suspend(struc + + vc4_irq_disable(&vc4->base); + ++ /* we no longer require a minimum clock rate */ ++ clk_set_min_rate(v3d->clk, 0); + clk_disable_unprepare(v3d->clk); + + return 0; diff --git a/target/linux/bcm27xx/patches-6.6/950-1324-dts-bcm2712-rpi-Add-aliases-for-the-CSI-DSI-I2Cs.patch b/target/linux/bcm27xx/patches-6.6/950-1324-dts-bcm2712-rpi-Add-aliases-for-the-CSI-DSI-I2Cs.patch new file mode 100644 index 00000000000..8781590f2e6 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1324-dts-bcm2712-rpi-Add-aliases-for-the-CSI-DSI-I2Cs.patch @@ -0,0 +1,71 @@ +From 36faab69e8eebfb7f587bddef96040c59d3daa7c Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 16 Oct 2024 11:31:04 +0100 +Subject: [PATCH 1324/1350] dts: bcm2712-rpi: Add aliases for the CSI/DSI I2Cs + +Older Pis arrange that the camera I2C ports appear as /dev/i2c-10. Add +aliases so that on the Pi 5 family, i2c_csi_dsi0 becomes i2c-10 and +i2c_csi_dsi1 becomes i2c-11. Only the I2C buses that appear on the +40-pin header, i.e. I2C0 to I2C3, get a low bus number. + +Also add hints for our udev rules about which symlinks to create for +backwards-compatibility with the previous bus numbers. Note that +lower numbers have priority, so i2c-0 on CM5 masks i2c-11, forcing +i2c-11 to be a symlink to i2c-0, not vice versa. + +Signed-off-by: Phil Elwell +--- + arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts | 2 ++ + arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5.dtsi | 2 ++ + arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi | 7 +++---- + 3 files changed, 7 insertions(+), 4 deletions(-) + +--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts ++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts +@@ -255,12 +255,14 @@ i2c_csi_dsi0: &i2c6 { // Note: This is f + pinctrl-0 = <&rp1_i2c6_38_39>; + pinctrl-names = "default"; + clock-frequency = <100000>; ++ symlink = "i2c-6"; + }; + + i2c_csi_dsi1: &i2c4 { // Note: This is for MIPI1 connector only + pinctrl-0 = <&rp1_i2c4_40_41>; + pinctrl-names = "default"; + clock-frequency = <100000>; ++ symlink = "i2c-4"; + }; + + i2c_csi_dsi: &i2c_csi_dsi1 { }; // An alias for compatibility +--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5.dtsi ++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5.dtsi +@@ -238,9 +238,11 @@ i2c_csi_dsi0: &i2c6 { // Note: This is f + pinctrl-0 = <&rp1_i2c6_38_39>; + pinctrl-names = "default"; + clock-frequency = <100000>; ++ symlink = "i2c-6"; + }; + + i2c_csi_dsi1: &i2c0 { // Note: This is for MIPI1 connector ++ symlink = "i2c-11"; + }; + + i2c_csi_dsi: &i2c_csi_dsi1 { }; // An alias for compatibility +--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi ++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi +@@ -117,12 +117,11 @@ + i2c = &i2c_arm; + i2c0 = &i2c0; + i2c1 = &i2c1; +- i2c10 = &i2c_rp1boot; + i2c2 = &i2c2; + i2c3 = &i2c3; +- i2c4 = &i2c4; +- i2c5 = &i2c5; +- i2c6 = &i2c6; ++ i2c10 = &i2c_csi_dsi0; ++ i2c11 = &i2c_csi_dsi1; ++ i2c12 = &i2c_rp1boot; + mailbox = &mailbox; + mmc0 = &sdio1; + serial0 = &uart0; diff --git a/target/linux/bcm27xx/patches-6.6/950-1325-NotForUpstream-media-video-mux-Propagate-controls-to.patch b/target/linux/bcm27xx/patches-6.6/950-1325-NotForUpstream-media-video-mux-Propagate-controls-to.patch new file mode 100644 index 00000000000..c40c3d27c14 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1325-NotForUpstream-media-video-mux-Propagate-controls-to.patch @@ -0,0 +1,51 @@ +From e03a63b8d4a60ee49e3277ac7f7ea4c2998e7938 Mon Sep 17 00:00:00 2001 +From: Kieran Bingham +Date: Thu, 10 Oct 2024 14:52:52 +0100 +Subject: [PATCH 1325/1350] NotForUpstream: media: video-mux: Propagate + controls to source + +The i.MX8MP makes calls on it's source device to determine +the link-frequency that should be configured on the CSI2 receiver. + +When the source is behind a video mux, we need to pass this call through +to the connected device. + +Map the control handler of the source device to the video-mux, +essentially proxying all controls on the mux to the device which has +it's link enabled. + +Signed-off-by: Kieran Bingham +--- + drivers/media/platform/video-mux.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/media/platform/video-mux.c ++++ b/drivers/media/platform/video-mux.c +@@ -69,6 +69,7 @@ static int video_mux_link_setup(struct m + const struct media_pad *remote, u32 flags) + { + struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); ++ struct v4l2_subdev *source_sd; + struct video_mux *vmux = v4l2_subdev_to_video_mux(sd); + u16 source_pad = entity->num_pads - 1; + int ret = 0; +@@ -111,6 +112,10 @@ static int video_mux_link_setup(struct m + *source_mbusformat = *v4l2_subdev_get_pad_format(sd, sd_state, + vmux->active); + v4l2_subdev_unlock_state(sd_state); ++ ++ source_sd = media_entity_to_v4l2_subdev(remote->entity); ++ vmux->subdev.ctrl_handler = source_sd->ctrl_handler; ++ + } else { + if (vmux->active != local->index) + goto out; +@@ -118,6 +123,8 @@ static int video_mux_link_setup(struct m + dev_dbg(sd->dev, "going inactive\n"); + mux_control_deselect(vmux->mux); + vmux->active = -1; ++ ++ vmux->subdev.ctrl_handler = NULL; + } + + out: diff --git a/target/linux/bcm27xx/patches-6.6/950-1326-media-platform-video-mux-Fix-mutex-locking.patch b/target/linux/bcm27xx/patches-6.6/950-1326-media-platform-video-mux-Fix-mutex-locking.patch new file mode 100644 index 00000000000..12b08b8188f --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1326-media-platform-video-mux-Fix-mutex-locking.patch @@ -0,0 +1,59 @@ +From cc0c868b51941f0ff2676970b70d388f1722e7fe Mon Sep 17 00:00:00 2001 +From: Paul Elder +Date: Thu, 10 Oct 2024 14:52:53 +0100 +Subject: [PATCH 1326/1350] media: platform: video-mux: Fix mutex locking + +The current order of locking between the driver mutex and the v4l2 +subdev state lock causes a circuluar locking dependency when trying to +set up a link. Fix this. + +Signed-off-by: Paul Elder +Reviewed-by: Laurent Pinchart +Signed-off-by: Kieran Bingham +--- + drivers/media/platform/video-mux.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/media/platform/video-mux.c ++++ b/drivers/media/platform/video-mux.c +@@ -70,6 +70,7 @@ static int video_mux_link_setup(struct m + { + struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); + struct v4l2_subdev *source_sd; ++ struct v4l2_subdev_state *sd_state; + struct video_mux *vmux = v4l2_subdev_to_video_mux(sd); + u16 source_pad = entity->num_pads - 1; + int ret = 0; +@@ -85,10 +86,10 @@ static int video_mux_link_setup(struct m + remote->entity->name, remote->index, local->entity->name, + local->index, flags & MEDIA_LNK_FL_ENABLED); + ++ sd_state = v4l2_subdev_lock_and_get_active_state(sd); + mutex_lock(&vmux->lock); + + if (flags & MEDIA_LNK_FL_ENABLED) { +- struct v4l2_subdev_state *sd_state; + struct v4l2_mbus_framefmt *source_mbusformat; + + if (vmux->active == local->index) +@@ -106,12 +107,10 @@ static int video_mux_link_setup(struct m + vmux->active = local->index; + + /* Propagate the active format to the source */ +- sd_state = v4l2_subdev_lock_and_get_active_state(sd); + source_mbusformat = v4l2_subdev_get_pad_format(sd, sd_state, + source_pad); + *source_mbusformat = *v4l2_subdev_get_pad_format(sd, sd_state, + vmux->active); +- v4l2_subdev_unlock_state(sd_state); + + source_sd = media_entity_to_v4l2_subdev(remote->entity); + vmux->subdev.ctrl_handler = source_sd->ctrl_handler; +@@ -129,6 +128,7 @@ static int video_mux_link_setup(struct m + + out: + mutex_unlock(&vmux->lock); ++ v4l2_subdev_unlock_state(sd_state); + return ret; + } + diff --git a/target/linux/bcm27xx/patches-6.6/950-1327-media-i2c-ov5647-Tidy-up-mode-registers-to-make-the-.patch b/target/linux/bcm27xx/patches-6.6/950-1327-media-i2c-ov5647-Tidy-up-mode-registers-to-make-the-.patch new file mode 100644 index 00000000000..3f0a34e4646 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1327-media-i2c-ov5647-Tidy-up-mode-registers-to-make-the-.patch @@ -0,0 +1,94 @@ +From 664e835fd4886332ec3b3813de47102fe45e4fc3 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 15 Oct 2024 16:05:57 +0100 +Subject: [PATCH 1327/1350] media: i2c: ov5647: Tidy up mode registers to make + the order common + +To make comparisons of the mode registers easier, put the registers +for the binned and VGA modes in the same order as the others. + +Signed-off-by: Dave Stevenson +--- + drivers/media/i2c/ov5647.c | 33 ++++++++++++++------------------- + 1 file changed, 14 insertions(+), 19 deletions(-) + +--- a/drivers/media/i2c/ov5647.c ++++ b/drivers/media/i2c/ov5647.c +@@ -344,6 +344,8 @@ static struct regval_list ov5647_2x2binn + {0x3036, 0x62}, + {0x303c, 0x11}, + {0x3106, 0xf5}, ++ {0x3821, 0x01}, ++ {0x3820, 0x41}, + {0x3827, 0xec}, + {0x370c, 0x03}, + {0x3612, 0x59}, +@@ -416,8 +418,6 @@ static struct regval_list ov5647_2x2binn + {0x4837, 0x16}, + {0x4800, 0x24}, + {0x3503, 0x03}, +- {0x3820, 0x41}, +- {0x3821, 0x01}, + {0x350a, 0x00}, + {0x350b, 0x10}, + {0x3500, 0x00}, +@@ -430,20 +430,27 @@ static struct regval_list ov5647_2x2binn + static struct regval_list ov5647_640x480_10bpp[] = { + {0x0100, 0x00}, + {0x0103, 0x01}, +- {0x3035, 0x11}, ++ {0x3034, 0x1a}, ++ {0x3035, 0x21}, + {0x3036, 0x46}, + {0x303c, 0x11}, ++ {0x3106, 0xf5}, + {0x3821, 0x01}, + {0x3820, 0x41}, ++ {0x3827, 0xec}, + {0x370c, 0x03}, + {0x3612, 0x59}, + {0x3618, 0x00}, + {0x5000, 0x06}, + {0x5003, 0x08}, + {0x5a00, 0x08}, +- {0x3000, 0xff}, +- {0x3001, 0xff}, +- {0x3002, 0xff}, ++ {0x3000, 0x00}, ++ {0x3001, 0x00}, ++ {0x3002, 0x00}, ++ {0x3016, 0x08}, ++ {0x3017, 0xe0}, ++ {0x3018, 0x44}, ++ {0x301c, 0xf8}, + {0x301d, 0xf0}, + {0x3a18, 0x00}, + {0x3a19, 0xf8}, +@@ -469,6 +476,7 @@ static struct regval_list ov5647_640x480 + {0x3632, 0xe2}, + {0x3633, 0x23}, + {0x3634, 0x44}, ++ {0x3636, 0x06}, + {0x3620, 0x64}, + {0x3621, 0xe0}, + {0x3600, 0x37}, +@@ -497,19 +505,6 @@ static struct regval_list ov5647_640x480 + {0x4001, 0x02}, + {0x4004, 0x02}, + {0x4000, 0x09}, +- {0x3000, 0x00}, +- {0x3001, 0x00}, +- {0x3002, 0x00}, +- {0x3017, 0xe0}, +- {0x301c, 0xfc}, +- {0x3636, 0x06}, +- {0x3016, 0x08}, +- {0x3827, 0xec}, +- {0x3018, 0x44}, +- {0x3035, 0x21}, +- {0x3106, 0xf5}, +- {0x3034, 0x1a}, +- {0x301c, 0xf8}, + {0x4800, 0x34}, + {0x3503, 0x03}, + {0x0100, 0x01}, diff --git a/target/linux/bcm27xx/patches-6.6/950-1328-media-i2c-ov5647-Separate-out-the-common-registers.patch b/target/linux/bcm27xx/patches-6.6/950-1328-media-i2c-ov5647-Separate-out-the-common-registers.patch new file mode 100644 index 00000000000..7f979e35e3a --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1328-media-i2c-ov5647-Separate-out-the-common-registers.patch @@ -0,0 +1,392 @@ +From aef1e51838641a602e0ab60523283f8a6e36a725 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 15 Oct 2024 17:02:39 +0100 +Subject: [PATCH 1328/1350] media: i2c: ov5647: Separate out the common + registers. + +There are many registers in common between all the modes. +Pull those out into one common table. + +Signed-off-by: Dave Stevenson +--- + drivers/media/i2c/ov5647.c | 243 ++++++++----------------------------- + 1 file changed, 50 insertions(+), 193 deletions(-) + +--- a/drivers/media/i2c/ov5647.c ++++ b/drivers/media/i2c/ov5647.c +@@ -162,22 +162,16 @@ static const struct regval_list sensor_o + {0x3002, 0xe4}, + }; + +-static struct regval_list ov5647_2592x1944_10bpp[] = { ++static struct regval_list ov5647_common_regs[] = { + {0x0100, 0x00}, + {0x0103, 0x01}, + {0x3034, 0x1a}, + {0x3035, 0x21}, +- {0x3036, 0x69}, + {0x303c, 0x11}, + {0x3106, 0xf5}, +- {0x3821, 0x00}, +- {0x3820, 0x00}, + {0x3827, 0xec}, + {0x370c, 0x03}, +- {0x3612, 0x5b}, +- {0x3618, 0x04}, + {0x5000, 0x06}, +- {0x5002, 0x41}, + {0x5003, 0x08}, + {0x5a00, 0x08}, + {0x3000, 0x00}, +@@ -192,24 +186,6 @@ static struct regval_list ov5647_2592x19 + {0x3a19, 0xf8}, + {0x3c01, 0x80}, + {0x3b07, 0x0c}, +- {0x3814, 0x11}, +- {0x3815, 0x11}, +- {0x3708, 0x64}, +- {0x3709, 0x12}, +- {0x3808, 0x0a}, +- {0x3809, 0x20}, +- {0x380a, 0x07}, +- {0x380b, 0x98}, +- {0x3800, 0x00}, +- {0x3801, 0x00}, +- {0x3802, 0x00}, +- {0x3803, 0x00}, +- {0x3804, 0x0a}, +- {0x3805, 0x3f}, +- {0x3806, 0x07}, +- {0x3807, 0xa3}, +- {0x3811, 0x10}, +- {0x3813, 0x06}, + {0x3630, 0x2e}, + {0x3632, 0xe2}, + {0x3633, 0x23}, +@@ -229,11 +205,6 @@ static struct regval_list ov5647_2592x19 + {0x3f06, 0x10}, + {0x3f01, 0x0a}, + {0x3a08, 0x01}, +- {0x3a09, 0x28}, +- {0x3a0a, 0x00}, +- {0x3a0b, 0xf6}, +- {0x3a0d, 0x08}, +- {0x3a0e, 0x06}, + {0x3a0f, 0x58}, + {0x3a10, 0x50}, + {0x3a1b, 0x58}, +@@ -241,52 +212,57 @@ static struct regval_list ov5647_2592x19 + {0x3a11, 0x60}, + {0x3a1f, 0x28}, + {0x4001, 0x02}, +- {0x4004, 0x04}, + {0x4000, 0x09}, ++ {0x3503, 0x03}, ++}; ++ ++static struct regval_list ov5647_2592x1944_10bpp[] = { ++ {0x3036, 0x69}, ++ {0x3821, 0x00}, ++ {0x3820, 0x00}, ++ {0x3612, 0x5b}, ++ {0x3618, 0x04}, ++ {0x5002, 0x41}, ++ {0x3814, 0x11}, ++ {0x3815, 0x11}, ++ {0x3708, 0x64}, ++ {0x3709, 0x12}, ++ {0x3800, 0x00}, ++ {0x3801, 0x00}, ++ {0x3802, 0x00}, ++ {0x3803, 0x00}, ++ {0x3804, 0x0a}, ++ {0x3805, 0x3f}, ++ {0x3806, 0x07}, ++ {0x3807, 0xa3}, ++ {0x3808, 0x0a}, ++ {0x3809, 0x20}, ++ {0x380a, 0x07}, ++ {0x380b, 0x98}, ++ {0x3811, 0x10}, ++ {0x3813, 0x06}, ++ {0x3a09, 0x28}, ++ {0x3a0a, 0x00}, ++ {0x3a0b, 0xf6}, ++ {0x3a0d, 0x08}, ++ {0x3a0e, 0x06}, ++ {0x4004, 0x04}, + {0x4837, 0x19}, + {0x4800, 0x24}, +- {0x3503, 0x03}, + {0x0100, 0x01}, + }; + + static struct regval_list ov5647_1080p30_10bpp[] = { +- {0x0100, 0x00}, +- {0x0103, 0x01}, +- {0x3034, 0x1a}, +- {0x3035, 0x21}, + {0x3036, 0x62}, +- {0x303c, 0x11}, +- {0x3106, 0xf5}, + {0x3821, 0x00}, + {0x3820, 0x00}, +- {0x3827, 0xec}, +- {0x370c, 0x03}, + {0x3612, 0x5b}, + {0x3618, 0x04}, +- {0x5000, 0x06}, + {0x5002, 0x41}, +- {0x5003, 0x08}, +- {0x5a00, 0x08}, +- {0x3000, 0x00}, +- {0x3001, 0x00}, +- {0x3002, 0x00}, +- {0x3016, 0x08}, +- {0x3017, 0xe0}, +- {0x3018, 0x44}, +- {0x301c, 0xf8}, +- {0x301d, 0xf0}, +- {0x3a18, 0x00}, +- {0x3a19, 0xf8}, +- {0x3c01, 0x80}, +- {0x3b07, 0x0c}, + {0x3814, 0x11}, + {0x3815, 0x11}, + {0x3708, 0x64}, + {0x3709, 0x12}, +- {0x3808, 0x07}, +- {0x3809, 0x80}, +- {0x380a, 0x04}, +- {0x380b, 0x38}, + {0x3800, 0x01}, + {0x3801, 0x5c}, + {0x3802, 0x01}, +@@ -295,77 +271,30 @@ static struct regval_list ov5647_1080p30 + {0x3805, 0xe3}, + {0x3806, 0x05}, + {0x3807, 0xf1}, ++ {0x3808, 0x07}, ++ {0x3809, 0x80}, ++ {0x380a, 0x04}, ++ {0x380b, 0x38}, + {0x3811, 0x04}, + {0x3813, 0x02}, +- {0x3630, 0x2e}, +- {0x3632, 0xe2}, +- {0x3633, 0x23}, +- {0x3634, 0x44}, +- {0x3636, 0x06}, +- {0x3620, 0x64}, +- {0x3621, 0xe0}, +- {0x3600, 0x37}, +- {0x3704, 0xa0}, +- {0x3703, 0x5a}, +- {0x3715, 0x78}, +- {0x3717, 0x01}, +- {0x3731, 0x02}, +- {0x370b, 0x60}, +- {0x3705, 0x1a}, +- {0x3f05, 0x02}, +- {0x3f06, 0x10}, +- {0x3f01, 0x0a}, +- {0x3a08, 0x01}, + {0x3a09, 0x4b}, + {0x3a0a, 0x01}, + {0x3a0b, 0x13}, + {0x3a0d, 0x04}, + {0x3a0e, 0x03}, +- {0x3a0f, 0x58}, +- {0x3a10, 0x50}, +- {0x3a1b, 0x58}, +- {0x3a1e, 0x50}, +- {0x3a11, 0x60}, +- {0x3a1f, 0x28}, +- {0x4001, 0x02}, + {0x4004, 0x04}, +- {0x4000, 0x09}, + {0x4837, 0x19}, + {0x4800, 0x34}, +- {0x3503, 0x03}, + {0x0100, 0x01}, + }; + + static struct regval_list ov5647_2x2binned_10bpp[] = { +- {0x0100, 0x00}, +- {0x0103, 0x01}, +- {0x3034, 0x1a}, +- {0x3035, 0x21}, + {0x3036, 0x62}, +- {0x303c, 0x11}, +- {0x3106, 0xf5}, + {0x3821, 0x01}, + {0x3820, 0x41}, +- {0x3827, 0xec}, +- {0x370c, 0x03}, + {0x3612, 0x59}, + {0x3618, 0x00}, +- {0x5000, 0x06}, + {0x5002, 0x41}, +- {0x5003, 0x08}, +- {0x5a00, 0x08}, +- {0x3000, 0x00}, +- {0x3001, 0x00}, +- {0x3002, 0x00}, +- {0x3016, 0x08}, +- {0x3017, 0xe0}, +- {0x3018, 0x44}, +- {0x301c, 0xf8}, +- {0x301d, 0xf0}, +- {0x3a18, 0x00}, +- {0x3a19, 0xf8}, +- {0x3c01, 0x80}, +- {0x3b07, 0x0c}, + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, +@@ -382,42 +311,14 @@ static struct regval_list ov5647_2x2binn + {0x3813, 0x06}, + {0x3814, 0x31}, + {0x3815, 0x31}, +- {0x3630, 0x2e}, +- {0x3632, 0xe2}, +- {0x3633, 0x23}, +- {0x3634, 0x44}, +- {0x3636, 0x06}, +- {0x3620, 0x64}, +- {0x3621, 0xe0}, +- {0x3600, 0x37}, +- {0x3704, 0xa0}, +- {0x3703, 0x5a}, +- {0x3715, 0x78}, +- {0x3717, 0x01}, +- {0x3731, 0x02}, +- {0x370b, 0x60}, +- {0x3705, 0x1a}, +- {0x3f05, 0x02}, +- {0x3f06, 0x10}, +- {0x3f01, 0x0a}, +- {0x3a08, 0x01}, + {0x3a09, 0x28}, + {0x3a0a, 0x00}, + {0x3a0b, 0xf6}, + {0x3a0d, 0x08}, + {0x3a0e, 0x06}, +- {0x3a0f, 0x58}, +- {0x3a10, 0x50}, +- {0x3a1b, 0x58}, +- {0x3a1e, 0x50}, +- {0x3a11, 0x60}, +- {0x3a1f, 0x28}, +- {0x4001, 0x02}, + {0x4004, 0x04}, +- {0x4000, 0x09}, + {0x4837, 0x16}, + {0x4800, 0x24}, +- {0x3503, 0x03}, + {0x350a, 0x00}, + {0x350b, 0x10}, + {0x3500, 0x00}, +@@ -428,42 +329,15 @@ static struct regval_list ov5647_2x2binn + }; + + static struct regval_list ov5647_640x480_10bpp[] = { +- {0x0100, 0x00}, +- {0x0103, 0x01}, +- {0x3034, 0x1a}, +- {0x3035, 0x21}, + {0x3036, 0x46}, +- {0x303c, 0x11}, +- {0x3106, 0xf5}, + {0x3821, 0x01}, + {0x3820, 0x41}, +- {0x3827, 0xec}, +- {0x370c, 0x03}, + {0x3612, 0x59}, + {0x3618, 0x00}, +- {0x5000, 0x06}, +- {0x5003, 0x08}, +- {0x5a00, 0x08}, +- {0x3000, 0x00}, +- {0x3001, 0x00}, +- {0x3002, 0x00}, +- {0x3016, 0x08}, +- {0x3017, 0xe0}, +- {0x3018, 0x44}, +- {0x301c, 0xf8}, +- {0x301d, 0xf0}, +- {0x3a18, 0x00}, +- {0x3a19, 0xf8}, +- {0x3c01, 0x80}, +- {0x3b07, 0x0c}, + {0x3814, 0x35}, + {0x3815, 0x35}, + {0x3708, 0x64}, + {0x3709, 0x52}, +- {0x3808, 0x02}, +- {0x3809, 0x80}, +- {0x380a, 0x01}, +- {0x380b, 0xe0}, + {0x3800, 0x00}, + {0x3801, 0x10}, + {0x3802, 0x00}, +@@ -472,41 +346,17 @@ static struct regval_list ov5647_640x480 + {0x3805, 0x2f}, + {0x3806, 0x07}, + {0x3807, 0x9f}, +- {0x3630, 0x2e}, +- {0x3632, 0xe2}, +- {0x3633, 0x23}, +- {0x3634, 0x44}, +- {0x3636, 0x06}, +- {0x3620, 0x64}, +- {0x3621, 0xe0}, +- {0x3600, 0x37}, +- {0x3704, 0xa0}, +- {0x3703, 0x5a}, +- {0x3715, 0x78}, +- {0x3717, 0x01}, +- {0x3731, 0x02}, +- {0x370b, 0x60}, +- {0x3705, 0x1a}, +- {0x3f05, 0x02}, +- {0x3f06, 0x10}, +- {0x3f01, 0x0a}, +- {0x3a08, 0x01}, ++ {0x3808, 0x02}, ++ {0x3809, 0x80}, ++ {0x380a, 0x01}, ++ {0x380b, 0xe0}, + {0x3a09, 0x2e}, + {0x3a0a, 0x00}, + {0x3a0b, 0xfb}, + {0x3a0d, 0x02}, + {0x3a0e, 0x01}, +- {0x3a0f, 0x58}, +- {0x3a10, 0x50}, +- {0x3a1b, 0x58}, +- {0x3a1e, 0x50}, +- {0x3a11, 0x60}, +- {0x3a1f, 0x28}, +- {0x4001, 0x02}, + {0x4004, 0x02}, +- {0x4000, 0x09}, + {0x4800, 0x34}, +- {0x3503, 0x03}, + {0x0100, 0x01}, + }; + +@@ -715,6 +565,13 @@ static int ov5647_set_mode(struct v4l2_s + if (ret < 0) + return ret; + ++ ret = ov5647_write_array(sd, ov5647_common_regs, ++ ARRAY_SIZE(ov5647_common_regs)); ++ if (ret < 0) { ++ dev_err(&client->dev, "write sensor common regs error\n"); ++ return ret; ++ } ++ + ret = ov5647_write_array(sd, sensor->mode->reg_list, + sensor->mode->num_regs); + if (ret < 0) { diff --git a/target/linux/bcm27xx/patches-6.6/950-1329-media-i2c-ov5647-Use-the-same-PLL-config-for-full-10.patch b/target/linux/bcm27xx/patches-6.6/950-1329-media-i2c-ov5647-Use-the-same-PLL-config-for-full-10.patch new file mode 100644 index 00000000000..c272951c6ff --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1329-media-i2c-ov5647-Use-the-same-PLL-config-for-full-10.patch @@ -0,0 +1,53 @@ +From 35e5c3d706cbe686e3468d9f24ae999212553893 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 15 Oct 2024 19:36:13 +0100 +Subject: [PATCH 1329/1350] media: i2c: ov5647: Use the same PLL config for + full, 1080p, and binned modes + +In order to simplify the driver slightly, use the same PLL +configuration, and hence pixel rate and link frequency (to be +added) for the full, 1080p, and binned modes. + +Signed-off-by: Dave Stevenson +--- + drivers/media/i2c/ov5647.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/media/i2c/ov5647.c ++++ b/drivers/media/i2c/ov5647.c +@@ -253,7 +253,7 @@ static struct regval_list ov5647_2592x19 + }; + + static struct regval_list ov5647_1080p30_10bpp[] = { +- {0x3036, 0x62}, ++ {0x3036, 0x69}, + {0x3821, 0x00}, + {0x3820, 0x00}, + {0x3612, 0x5b}, +@@ -289,7 +289,7 @@ static struct regval_list ov5647_1080p30 + }; + + static struct regval_list ov5647_2x2binned_10bpp[] = { +- {0x3036, 0x62}, ++ {0x3036, 0x69}, + {0x3821, 0x01}, + {0x3820, 0x41}, + {0x3612, 0x59}, +@@ -397,7 +397,7 @@ static const struct ov5647_mode ov5647_m + .width = 1928, + .height = 1080, + }, +- .pixel_rate = 81666700, ++ .pixel_rate = 87500000, + .hts = 2416, + .vts = 0x450, + .reg_list = ov5647_1080p30_10bpp, +@@ -418,7 +418,7 @@ static const struct ov5647_mode ov5647_m + .width = 2592, + .height = 1944, + }, +- .pixel_rate = 81666700, ++ .pixel_rate = 87500000, + .hts = 1896, + .vts = 0x59b, + .reg_list = ov5647_2x2binned_10bpp, diff --git a/target/linux/bcm27xx/patches-6.6/950-1330-media-i2c-ov5647-Add-V4L2_CID_LINK_FREQUENCY-control.patch b/target/linux/bcm27xx/patches-6.6/950-1330-media-i2c-ov5647-Add-V4L2_CID_LINK_FREQUENCY-control.patch new file mode 100644 index 00000000000..efe47592d7c --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1330-media-i2c-ov5647-Add-V4L2_CID_LINK_FREQUENCY-control.patch @@ -0,0 +1,111 @@ +From 84ab77459e61c648299d32464127b89ca65de40a Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 15 Oct 2024 19:46:01 +0100 +Subject: [PATCH 1330/1350] media: i2c: ov5647: Add V4L2_CID_LINK_FREQUENCY + control + +The link frequency can vary between modes, so add it as a +control. + +Signed-off-by: Dave Stevenson +--- + drivers/media/i2c/ov5647.c | 25 ++++++++++++++++++++++++- + 1 file changed, 24 insertions(+), 1 deletion(-) + +--- a/drivers/media/i2c/ov5647.c ++++ b/drivers/media/i2c/ov5647.c +@@ -97,6 +97,13 @@ static const char * const ov5647_supply_ + + #define OV5647_NUM_SUPPLIES ARRAY_SIZE(ov5647_supply_names) + ++#define FREQ_INDEX_FULL 0 ++#define FREQ_INDEX_VGA 1 ++static const s64 ov5647_link_freqs[] = { ++ [FREQ_INDEX_FULL] = 218500000, ++ [FREQ_INDEX_VGA] = 208333000, ++}; ++ + struct regval_list { + u16 addr; + u8 data; +@@ -106,6 +113,7 @@ struct ov5647_mode { + struct v4l2_mbus_framefmt format; + struct v4l2_rect crop; + u64 pixel_rate; ++ unsigned int link_freq_index; + int hts; + int vts; + const struct regval_list *reg_list; +@@ -128,6 +136,7 @@ struct ov5647 { + struct v4l2_ctrl *exposure; + struct v4l2_ctrl *hflip; + struct v4l2_ctrl *vflip; ++ struct v4l2_ctrl *link_freq; + bool streaming; + }; + +@@ -377,6 +386,7 @@ static const struct ov5647_mode ov5647_m + .height = 1944 + }, + .pixel_rate = 87500000, ++ .link_freq_index = FREQ_INDEX_FULL, + .hts = 2844, + .vts = 0x7b0, + .reg_list = ov5647_2592x1944_10bpp, +@@ -398,6 +408,7 @@ static const struct ov5647_mode ov5647_m + .height = 1080, + }, + .pixel_rate = 87500000, ++ .link_freq_index = FREQ_INDEX_FULL, + .hts = 2416, + .vts = 0x450, + .reg_list = ov5647_1080p30_10bpp, +@@ -419,6 +430,7 @@ static const struct ov5647_mode ov5647_m + .height = 1944, + }, + .pixel_rate = 87500000, ++ .link_freq_index = FREQ_INDEX_FULL, + .hts = 1896, + .vts = 0x59b, + .reg_list = ov5647_2x2binned_10bpp, +@@ -440,6 +452,7 @@ static const struct ov5647_mode ov5647_m + .height = 1920, + }, + .pixel_rate = 55000000, ++ .link_freq_index = FREQ_INDEX_VGA, + .hts = 1852, + .vts = 0x1f8, + .reg_list = ov5647_640x480_10bpp, +@@ -943,6 +956,8 @@ static int ov5647_set_pad_fmt(struct v4l + sensor->exposure->minimum, + exposure_max, sensor->exposure->step, + exposure_def); ++ ++ __v4l2_ctrl_s_ctrl(sensor->link_freq, mode->link_freq_index); + } + *fmt = mode->format; + /* The code we pass back must reflect the current h/vflips. */ +@@ -1248,7 +1263,7 @@ static int ov5647_init_controls(struct o + int hblank, exposure_max, exposure_def; + struct v4l2_fwnode_device_properties props; + +- v4l2_ctrl_handler_init(&sensor->ctrls, 9); ++ v4l2_ctrl_handler_init(&sensor->ctrls, 10); + + v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops, + V4L2_CID_AUTOGAIN, 0, 1, 1, 0); +@@ -1308,6 +1323,14 @@ static int ov5647_init_controls(struct o + if (sensor->vflip) + sensor->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; + ++ sensor->link_freq = ++ v4l2_ctrl_new_int_menu(&sensor->ctrls, &ov5647_ctrl_ops, ++ V4L2_CID_LINK_FREQ, ++ ARRAY_SIZE(ov5647_link_freqs) - 1, 0, ++ ov5647_link_freqs); ++ if (sensor->link_freq) ++ sensor->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; ++ + v4l2_fwnode_device_parse(dev, &props); + + v4l2_ctrl_new_fwnode_properties(&sensor->ctrls, &ov5647_ctrl_ops, diff --git a/target/linux/bcm27xx/patches-6.6/950-1331-mmc-don-t-reference-requests-after-finishing-them.patch b/target/linux/bcm27xx/patches-6.6/950-1331-mmc-don-t-reference-requests-after-finishing-them.patch new file mode 100644 index 00000000000..c7d411f0e3d --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1331-mmc-don-t-reference-requests-after-finishing-them.patch @@ -0,0 +1,71 @@ +From b80d5d1d5148a89121e3759bb4caa27e7ee1cf05 Mon Sep 17 00:00:00 2001 +From: Jonathan Bell +Date: Tue, 15 Oct 2024 11:22:53 +0100 +Subject: [PATCH 1331/1350] mmc: don't reference requests after finishing them + +Posted write tracking introduced in the commit below raced with re-use +of the requests between completion and submission, potentially causing +underflow of the pending write count. + +Fixes: e6c1e862b2b8 ("mmc: restrict posted write counts for SD cards in CQ mode") + +Signed-off-by: Jonathan Bell +--- + drivers/mmc/core/block.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +--- a/drivers/mmc/core/block.c ++++ b/drivers/mmc/core/block.c +@@ -1524,6 +1524,7 @@ static void mmc_blk_cqe_complete_rq(stru + struct request_queue *q = req->q; + struct mmc_host *host = mq->card->host; + enum mmc_issue_type issue_type = mmc_issue_type(mq, req); ++ bool write = req_op(req) == REQ_OP_WRITE; + unsigned long flags; + bool put_card; + int err; +@@ -1555,7 +1556,7 @@ static void mmc_blk_cqe_complete_rq(stru + + spin_lock_irqsave(&mq->lock, flags); + +- if (req_op(req) == REQ_OP_WRITE) ++ if (write) + mq->pending_writes--; + mq->in_flight[issue_type] -= 1; + +@@ -2170,15 +2171,16 @@ static void mmc_blk_mq_poll_completion(s + } + + static void mmc_blk_mq_dec_in_flight(struct mmc_queue *mq, enum mmc_issue_type issue_type, +- struct request *req) ++ bool write) + { + unsigned long flags; + bool put_card; + + spin_lock_irqsave(&mq->lock, flags); + +- if (req_op(req) == REQ_OP_WRITE) ++ if (write) + mq->pending_writes--; ++ + mq->in_flight[issue_type] -= 1; + + put_card = (mmc_tot_in_flight(mq) == 0); +@@ -2193,6 +2195,7 @@ static void mmc_blk_mq_post_req(struct m + bool can_sleep) + { + enum mmc_issue_type issue_type = mmc_issue_type(mq, req); ++ bool write = req_op(req) == REQ_OP_WRITE; + struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req); + struct mmc_request *mrq = &mqrq->brq.mrq; + struct mmc_host *host = mq->card->host; +@@ -2212,7 +2215,7 @@ static void mmc_blk_mq_post_req(struct m + blk_mq_complete_request(req); + } + +- mmc_blk_mq_dec_in_flight(mq, issue_type, req); ++ mmc_blk_mq_dec_in_flight(mq, issue_type, write); + } + + void mmc_blk_mq_recovery(struct mmc_queue *mq) diff --git a/target/linux/bcm27xx/patches-6.6/950-1333-mmc-quirks-disable-cache-on-more-known-bad-Sandisk-c.patch b/target/linux/bcm27xx/patches-6.6/950-1333-mmc-quirks-disable-cache-on-more-known-bad-Sandisk-c.patch new file mode 100644 index 00000000000..109c502e13f --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1333-mmc-quirks-disable-cache-on-more-known-bad-Sandisk-c.patch @@ -0,0 +1,35 @@ +From 4d702b5c68d6449d81281677f71de557f64cdce5 Mon Sep 17 00:00:00 2001 +From: Jonathan Bell +Date: Tue, 15 Oct 2024 14:35:42 +0100 +Subject: [PATCH 1333/1350] mmc: quirks: disable cache on more known-bad + Sandisk card date ranges + +Cards with manufacture dates in 2019 and 2020 have been seen in the wild +that hang indefinitely if issued a cache flush command in CQ mode. + +Signed-off-by: Jonathan Bell +--- + drivers/mmc/core/quirks.h | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +--- a/drivers/mmc/core/quirks.h ++++ b/drivers/mmc/core/quirks.h +@@ -33,6 +33,18 @@ static const struct mmc_fixup __maybe_un + 0, -1ull, SDIO_ANY_ID, SDIO_ANY_ID, add_quirk_sd, + MMC_QUIRK_BROKEN_SD_CACHE, EXT_CSD_REV_ANY), + ++ /* ++ * Early Sandisk Extreme and Extreme Pro A2 cards never finish SD cache ++ * flush in CQ mode. Latest card date this was seen on is 10/2020. ++ */ ++ _FIXUP_EXT(CID_NAME_ANY, CID_MANFID_SANDISK_SD, 0x5344, 2019, CID_MONTH_ANY, ++ 0, -1ull, SDIO_ANY_ID, SDIO_ANY_ID, add_quirk_sd, ++ MMC_QUIRK_BROKEN_SD_CACHE, EXT_CSD_REV_ANY), ++ ++ _FIXUP_EXT(CID_NAME_ANY, CID_MANFID_SANDISK_SD, 0x5344, 2020, CID_MONTH_ANY, ++ 0, -1ull, SDIO_ANY_ID, SDIO_ANY_ID, add_quirk_sd, ++ MMC_QUIRK_BROKEN_SD_CACHE, EXT_CSD_REV_ANY), ++ + END_FIXUP + }; + diff --git a/target/linux/bcm27xx/patches-6.6/950-1334-mmc-block-disable-CQ-on-SD-cards-when-doing-non-Disc.patch b/target/linux/bcm27xx/patches-6.6/950-1334-mmc-block-disable-CQ-on-SD-cards-when-doing-non-Disc.patch new file mode 100644 index 00000000000..72a87e5978c --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1334-mmc-block-disable-CQ-on-SD-cards-when-doing-non-Disc.patch @@ -0,0 +1,55 @@ +From 73ddacb555c5ef1f063f44b4ec3268da899ff8b5 Mon Sep 17 00:00:00 2001 +From: Jonathan Bell +Date: Fri, 18 Oct 2024 13:11:11 +0100 +Subject: [PATCH 1334/1350] mmc: block: disable CQ on SD cards when doing + non-Discard erase + +Only CMD38 with Arg=0x1 (Discard) is supported when in CQ mode, so +turn it off before issuing a non-discard erase op. + +Signed-off-by: Jonathan Bell +--- + drivers/mmc/core/block.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +--- a/drivers/mmc/core/block.c ++++ b/drivers/mmc/core/block.c +@@ -1177,12 +1177,26 @@ static void mmc_blk_issue_erase_rq(struc + unsigned int from, nr; + int err = 0; + blk_status_t status = BLK_STS_OK; ++ bool restart_cmdq = false; + + if (!mmc_can_erase(card)) { + status = BLK_STS_NOTSUPP; + goto fail; + } + ++ /* ++ * Only Discard ops are supported with SD cards in CQ mode ++ * (SD Physical Spec v9.00 4.19.2) ++ */ ++ if (mmc_card_sd(card) && card->ext_csd.cmdq_en && erase_arg != SD_DISCARD_ARG) { ++ restart_cmdq = true; ++ err = mmc_sd_cmdq_disable(card); ++ if (err) { ++ status = BLK_STS_IOERR; ++ goto fail; ++ } ++ } ++ + from = blk_rq_pos(req); + nr = blk_rq_sectors(req); + +@@ -1203,6 +1217,11 @@ static void mmc_blk_issue_erase_rq(struc + status = BLK_STS_IOERR; + else + mmc_blk_reset_success(md, type); ++ ++ if (restart_cmdq) ++ err = mmc_sd_cmdq_enable(card); ++ if (err) ++ status = BLK_STS_IOERR; + fail: + blk_mq_end_request(req, status); + } diff --git a/target/linux/bcm27xx/patches-6.6/950-1208-DTS-bcm2712-enable-SD-slot-CQE-by-default-on-Pi-5.patch b/target/linux/bcm27xx/patches-6.6/950-1335-DTS-bcm2712-re-enable-SD-slot-CQE-by-default-on-Pi-5.patch similarity index 77% rename from target/linux/bcm27xx/patches-6.6/950-1208-DTS-bcm2712-enable-SD-slot-CQE-by-default-on-Pi-5.patch rename to target/linux/bcm27xx/patches-6.6/950-1335-DTS-bcm2712-re-enable-SD-slot-CQE-by-default-on-Pi-5.patch index 16e76034981..e6260e7249c 100644 --- a/target/linux/bcm27xx/patches-6.6/950-1208-DTS-bcm2712-enable-SD-slot-CQE-by-default-on-Pi-5.patch +++ b/target/linux/bcm27xx/patches-6.6/950-1335-DTS-bcm2712-re-enable-SD-slot-CQE-by-default-on-Pi-5.patch @@ -1,10 +1,10 @@ -From 216df57950849f905c398904e7d6cbdf278b5717 Mon Sep 17 00:00:00 2001 +From 48a15bc46004025776880a091d47a22e03449acc Mon Sep 17 00:00:00 2001 From: Jonathan Bell -Date: Mon, 5 Aug 2024 11:28:36 +0100 -Subject: [PATCH 1208/1215] DTS: bcm2712: enable SD slot CQE by default on Pi 5 +Date: Fri, 18 Oct 2024 14:06:01 +0100 +Subject: [PATCH 1335/1350] DTS: bcm2712; re-enable SD slot CQE by default on + Pi 5 -The corresponding driver implementation has seen sufficient testing, -so enable by default. Retain the dtparam so it can be turned off for test. +This reverts commit 1b92c9369569137d8f2b8bf82884a05999e1f73b. Signed-off-by: Jonathan Bell --- @@ -29,7 +29,7 @@ Signed-off-by: Jonathan Bell requests 50MHz --- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts +++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts -@@ -363,6 +363,7 @@ dpi_16bit_gpio2: &rp1_dpi_16bit_g +@@ -365,6 +365,7 @@ dpi_16bit_gpio2: &rp1_dpi_16bit_g sd-uhs-sdr50; sd-uhs-ddr50; sd-uhs-sdr104; diff --git a/target/linux/bcm27xx/patches-6.6/950-1336-mmc-quirks-add-MMC_QUIRK_BROKEN_ERASE-for-Phison-Int.patch b/target/linux/bcm27xx/patches-6.6/950-1336-mmc-quirks-add-MMC_QUIRK_BROKEN_ERASE-for-Phison-Int.patch new file mode 100644 index 00000000000..ba61b15ea15 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1336-mmc-quirks-add-MMC_QUIRK_BROKEN_ERASE-for-Phison-Int.patch @@ -0,0 +1,33 @@ +From 527d6f5a7861e24c60d41e9706ec4589165321d1 Mon Sep 17 00:00:00 2001 +From: Jonathan Bell +Date: Fri, 18 Oct 2024 16:01:28 +0100 +Subject: [PATCH 1336/1350] mmc: quirks: add MMC_QUIRK_BROKEN_ERASE for + Phison/Integral cards + +Recent Integral cards end up with corrupt sectors after a flash erase. +This covers sizes for the A2 range, which can't be differentiated from +the A1 range which might not have the same issue. + +Signed-off-by: Jonathan Bell +--- + drivers/mmc/core/quirks.h | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/drivers/mmc/core/quirks.h ++++ b/drivers/mmc/core/quirks.h +@@ -162,6 +162,15 @@ static const struct mmc_fixup __maybe_un + MMC_FIXUP("SD32G", 0x41, 0x3432, add_quirk, MMC_QUIRK_ERASE_BROKEN), + MMC_FIXUP("SD64G", 0x41, 0x3432, add_quirk, MMC_QUIRK_ERASE_BROKEN), + ++ /* ++ * Larger Integral SD cards using rebranded Phison controllers trash ++ * nearby flash blocks after erases. ++ */ ++ MMC_FIXUP("SD64G", 0x27, 0x5048, add_quirk, MMC_QUIRK_ERASE_BROKEN), ++ MMC_FIXUP("SD128", 0x27, 0x5048, add_quirk, MMC_QUIRK_ERASE_BROKEN), ++ MMC_FIXUP("SD256", 0x27, 0x5048, add_quirk, MMC_QUIRK_ERASE_BROKEN), ++ MMC_FIXUP("SD512", 0x27, 0x5048, add_quirk, MMC_QUIRK_ERASE_BROKEN), ++ + END_FIXUP + }; + diff --git a/target/linux/bcm27xx/patches-6.6/950-1337-Input-matrix_keypad-avoid-repeatedly-converting-GPIO.patch b/target/linux/bcm27xx/patches-6.6/950-1337-Input-matrix_keypad-avoid-repeatedly-converting-GPIO.patch new file mode 100644 index 00000000000..d9a7a10cd44 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1337-Input-matrix_keypad-avoid-repeatedly-converting-GPIO.patch @@ -0,0 +1,155 @@ +From 25b2b36dea57fd86b63df2e253b376532d314a30 Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Sat, 20 Jan 2024 21:32:28 -0800 +Subject: [PATCH 1337/1350] Input: matrix_keypad - avoid repeatedly converting + GPIO to IRQ + +commit a96fb711c6be76bcfbcf594a865002fa7c0eb525 upstream. + +There is no need to do conversion from GPIOs to interrupt numbers. +Convert row GPIOs to interrupt numbers once in probe() and use +this information when the driver needs to enable or disable given +interrupt line. + +Link: https://lore.kernel.org/r/20240121053232.276968-1-dmitry.torokhov@gmail.com +Signed-off-by: Dmitry Torokhov +--- + drivers/input/keyboard/matrix_keypad.c | 48 ++++++++++++++------------ + 1 file changed, 25 insertions(+), 23 deletions(-) + +--- a/drivers/input/keyboard/matrix_keypad.c ++++ b/drivers/input/keyboard/matrix_keypad.c +@@ -27,6 +27,7 @@ struct matrix_keypad { + const struct matrix_keypad_platform_data *pdata; + struct input_dev *input_dev; + unsigned int row_shift; ++ unsigned int row_irqs[MATRIX_MAX_ROWS]; + + DECLARE_BITMAP(disabled_gpios, MATRIX_MAX_ROWS); + +@@ -92,7 +93,7 @@ static void enable_row_irqs(struct matri + enable_irq(pdata->clustered_irq); + else { + for (i = 0; i < pdata->num_row_gpios; i++) +- enable_irq(gpio_to_irq(pdata->row_gpios[i])); ++ enable_irq(keypad->row_irqs[i]); + } + } + +@@ -105,7 +106,7 @@ static void disable_row_irqs(struct matr + disable_irq_nosync(pdata->clustered_irq); + else { + for (i = 0; i < pdata->num_row_gpios; i++) +- disable_irq_nosync(gpio_to_irq(pdata->row_gpios[i])); ++ disable_irq_nosync(keypad->row_irqs[i]); + } + } + +@@ -233,7 +234,6 @@ static void matrix_keypad_stop(struct in + static void matrix_keypad_enable_wakeup(struct matrix_keypad *keypad) + { + const struct matrix_keypad_platform_data *pdata = keypad->pdata; +- unsigned int gpio; + int i; + + if (pdata->clustered_irq > 0) { +@@ -241,21 +241,16 @@ static void matrix_keypad_enable_wakeup( + keypad->gpio_all_disabled = true; + } else { + +- for (i = 0; i < pdata->num_row_gpios; i++) { +- if (!test_bit(i, keypad->disabled_gpios)) { +- gpio = pdata->row_gpios[i]; +- +- if (enable_irq_wake(gpio_to_irq(gpio)) == 0) ++ for (i = 0; i < pdata->num_row_gpios; i++) ++ if (!test_bit(i, keypad->disabled_gpios)) ++ if (enable_irq_wake(keypad->row_irqs[i]) == 0) + __set_bit(i, keypad->disabled_gpios); +- } +- } + } + } + + static void matrix_keypad_disable_wakeup(struct matrix_keypad *keypad) + { + const struct matrix_keypad_platform_data *pdata = keypad->pdata; +- unsigned int gpio; + int i; + + if (pdata->clustered_irq > 0) { +@@ -264,12 +259,9 @@ static void matrix_keypad_disable_wakeup + keypad->gpio_all_disabled = false; + } + } else { +- for (i = 0; i < pdata->num_row_gpios; i++) { +- if (test_and_clear_bit(i, keypad->disabled_gpios)) { +- gpio = pdata->row_gpios[i]; +- disable_irq_wake(gpio_to_irq(gpio)); +- } +- } ++ for (i = 0; i < pdata->num_row_gpios; i++) ++ if (test_and_clear_bit(i, keypad->disabled_gpios)) ++ disable_irq_wake(keypad->row_irqs[i]); + } + } + +@@ -306,7 +298,7 @@ static int matrix_keypad_init_gpio(struc + struct matrix_keypad *keypad) + { + const struct matrix_keypad_platform_data *pdata = keypad->pdata; +- int i, err; ++ int i, irq, err; + + /* initialized strobe lines as outputs, activated */ + for (i = 0; i < pdata->num_col_gpios; i++) { +@@ -345,11 +337,19 @@ static int matrix_keypad_init_gpio(struc + } + } else { + for (i = 0; i < pdata->num_row_gpios; i++) { +- err = request_any_context_irq( +- gpio_to_irq(pdata->row_gpios[i]), ++ irq = gpio_to_irq(pdata->row_gpios[i]); ++ if (irq < 0) { ++ err = irq; ++ dev_err(&pdev->dev, ++ "Unable to convert GPIO line %i to irq: %d\n", ++ pdata->row_gpios[i], err); ++ goto err_free_irqs; ++ } ++ ++ err = request_any_context_irq(irq, + matrix_keypad_interrupt, + IRQF_TRIGGER_RISING | +- IRQF_TRIGGER_FALLING, ++ IRQF_TRIGGER_FALLING, + "matrix-keypad", keypad); + if (err < 0) { + dev_err(&pdev->dev, +@@ -357,6 +357,8 @@ static int matrix_keypad_init_gpio(struc + pdata->row_gpios[i]); + goto err_free_irqs; + } ++ ++ keypad->row_irqs[i] = irq; + } + } + +@@ -366,7 +368,7 @@ static int matrix_keypad_init_gpio(struc + + err_free_irqs: + while (--i >= 0) +- free_irq(gpio_to_irq(pdata->row_gpios[i]), keypad); ++ free_irq(keypad->row_irqs[i], keypad); + i = pdata->num_row_gpios; + err_free_rows: + while (--i >= 0) +@@ -388,7 +390,7 @@ static void matrix_keypad_free_gpio(stru + free_irq(pdata->clustered_irq, keypad); + } else { + for (i = 0; i < pdata->num_row_gpios; i++) +- free_irq(gpio_to_irq(pdata->row_gpios[i]), keypad); ++ free_irq(keypad->row_irqs[i], keypad); + } + + for (i = 0; i < pdata->num_row_gpios; i++) diff --git a/target/linux/bcm27xx/patches-6.6/950-1338-numa-Add-simple-generic-NUMA-emulation.patch b/target/linux/bcm27xx/patches-6.6/950-1338-numa-Add-simple-generic-NUMA-emulation.patch new file mode 100644 index 00000000000..afb1bf7c9ab --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1338-numa-Add-simple-generic-NUMA-emulation.patch @@ -0,0 +1,182 @@ +From b1a0f9c705912ec0434645f2d2bcf914c635564d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ma=C3=ADra=20Canal?= +Date: Fri, 17 May 2024 11:40:23 -0300 +Subject: [PATCH 1338/1350] numa: Add simple generic NUMA emulation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add some common code for splitting the memory into N emulated NUMA memory +nodes. + +Individual architecture can then enable selecting this option and use the +existing numa=fake= kernel argument to enable it. + +Memory is always split into equally sized chunks. + +Signed-off-by: Maíra Canal +Co-developed-by: Tvrtko Ursulin +Signed-off-by: Tvrtko Ursulin +Cc: Catalin Marinas +Cc: Will Deacon +Cc: Greg Kroah-Hartman +Cc: “Rafael J. Wysocki" +--- + drivers/base/Kconfig | 7 ++++ + drivers/base/Makefile | 1 + + drivers/base/arch_numa.c | 6 ++++ + drivers/base/numa_emulation.c | 67 +++++++++++++++++++++++++++++++++++ + drivers/base/numa_emulation.h | 21 +++++++++++ + 5 files changed, 102 insertions(+) + create mode 100644 drivers/base/numa_emulation.c + create mode 100644 drivers/base/numa_emulation.h + +--- a/drivers/base/Kconfig ++++ b/drivers/base/Kconfig +@@ -230,6 +230,13 @@ config GENERIC_ARCH_NUMA + Enable support for generic NUMA implementation. Currently, RISC-V + and ARM64 use it. + ++config GENERIC_ARCH_NUMA_EMULATION ++ bool ++ depends on GENERIC_ARCH_NUMA ++ help ++ Enable NUMA emulation. Note that NUMA emulation will only be used if ++ the machine has no NUMA node. ++ + config FW_DEVLINK_SYNC_STATE_TIMEOUT + bool "sync_state() behavior defaults to timeout instead of strict" + help +--- a/drivers/base/Makefile ++++ b/drivers/base/Makefile +@@ -25,6 +25,7 @@ obj-$(CONFIG_DEV_COREDUMP) += devcoredum + obj-$(CONFIG_GENERIC_MSI_IRQ) += platform-msi.o + obj-$(CONFIG_GENERIC_ARCH_TOPOLOGY) += arch_topology.o + obj-$(CONFIG_GENERIC_ARCH_NUMA) += arch_numa.o ++obj-$(CONFIG_GENERIC_ARCH_NUMA_EMULATION) += numa_emulation.o + obj-$(CONFIG_ACPI) += physical_location.o + + obj-y += test/ +--- a/drivers/base/arch_numa.c ++++ b/drivers/base/arch_numa.c +@@ -15,6 +15,8 @@ + + #include + ++#include "numa_emulation.h" ++ + struct pglist_data *node_data[MAX_NUMNODES] __read_mostly; + EXPORT_SYMBOL(node_data); + nodemask_t numa_nodes_parsed __initdata; +@@ -30,6 +32,8 @@ static __init int numa_parse_early_param + return -EINVAL; + if (str_has_prefix(opt, "off")) + numa_off = true; ++ if (str_has_prefix(opt, "fake=")) ++ return numa_emu_cmdline(opt + 5); + + return 0; + } +@@ -471,6 +475,8 @@ void __init arch_numa_init(void) + return; + if (acpi_disabled && !numa_init(of_numa_init)) + return; ++ if (!numa_init(numa_emu_init)) ++ return; + } + + numa_init(dummy_numa_init); +--- /dev/null ++++ b/drivers/base/numa_emulation.c +@@ -0,0 +1,67 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Simple NUMA emulation. ++ * ++ * Copyright © 2024 Raspberry Pi Ltd ++ * ++ * Author: Maíra Canal ++ * Author: Tvrtko Ursulin ++ */ ++#include ++ ++#include "numa_emulation.h" ++ ++static unsigned int emu_nodes; ++ ++int __init numa_emu_cmdline(char *str) ++{ ++ int ret; ++ ++ ret = kstrtouint(str, 10, &emu_nodes); ++ if (ret) ++ return ret; ++ ++ if (emu_nodes > MAX_NUMNODES) { ++ pr_notice("numa=fake=%u too large, reducing to %u\n", ++ emu_nodes, MAX_NUMNODES); ++ emu_nodes = MAX_NUMNODES; ++ } ++ ++ return 0; ++} ++ ++int __init numa_emu_init(void) ++{ ++ phys_addr_t start, end; ++ unsigned long size; ++ unsigned int i; ++ int ret; ++ ++ if (!emu_nodes) ++ return -EINVAL; ++ ++ start = memblock_start_of_DRAM(); ++ end = memblock_end_of_DRAM() - 1; ++ ++ size = DIV_ROUND_DOWN_ULL(end - start + 1, emu_nodes); ++ size = PAGE_ALIGN_DOWN(size); ++ ++ for (i = 0; i < emu_nodes; i++) { ++ u64 s, e; ++ ++ s = start + i * size; ++ e = s + size - 1; ++ ++ if (i == (emu_nodes - 1) && e != end) ++ e = end; ++ ++ pr_info("Faking a node at [mem %pap-%pap]\n", &s, &e); ++ ret = numa_add_memblk(i, s, e + 1); ++ if (ret) { ++ pr_err("Failed to add fake NUMA node %d!\n", i); ++ break; ++ } ++ } ++ ++ return ret; ++} +--- /dev/null ++++ b/drivers/base/numa_emulation.h +@@ -0,0 +1,21 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * NUMA emulation header ++ * ++ * Copyright © 2024 Raspberry Pi Ltd ++ */ ++ ++#ifdef CONFIG_GENERIC_ARCH_NUMA_EMULATION ++int numa_emu_cmdline(char *str); ++int __init numa_emu_init(void); ++#else ++static inline int numa_emu_cmdline(char *str) ++{ ++ return -EINVAL; ++} ++ ++static int __init numa_emu_init(void) ++{ ++ return -EOPNOTSUPP; ++} ++#endif /* CONFIG_NUMA_EMU */ diff --git a/target/linux/bcm27xx/patches-6.6/950-1339-arm64-numa-Add-NUMA-emulation-for-ARM64.patch b/target/linux/bcm27xx/patches-6.6/950-1339-arm64-numa-Add-NUMA-emulation-for-ARM64.patch new file mode 100644 index 00000000000..169706de8c8 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1339-arm64-numa-Add-NUMA-emulation-for-ARM64.patch @@ -0,0 +1,39 @@ +From 462346142b26dd1fd8f55655959e38b385acb1c1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ma=C3=ADra=20Canal?= +Date: Fri, 17 May 2024 11:40:34 -0300 +Subject: [PATCH 1339/1350] arm64/numa: Add NUMA emulation for ARM64 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Allow selecting NUMA emulation on arm64. + +Signed-off-by: Maíra Canal +Signed-off-by: Tvrtko Ursulin +Cc: Catalin Marinas +Cc: Will Deacon +Cc: Greg Kroah-Hartman +Cc: “Rafael J. Wysocki" +--- + arch/arm64/Kconfig | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/arch/arm64/Kconfig ++++ b/arch/arm64/Kconfig +@@ -1500,6 +1500,16 @@ config NODES_SHIFT + Specify the maximum number of NUMA Nodes available on the target + system. Increases memory reserved to accommodate various tables. + ++config NUMA_EMULATION ++ bool "NUMA emulation" ++ depends on NUMA ++ select GENERIC_ARCH_NUMA_EMULATION ++ help ++ Enable NUMA emulation support. A flat machine will be split into ++ virtual nodes when booted with "numa=fake=N", where N is the number ++ of nodes, the system RAM will be split into N equal chunks, and ++ assigned to each node. ++ + source "kernel/Kconfig.hz" + + config ARCH_SPARSEMEM_ENABLE diff --git a/target/linux/bcm27xx/patches-6.6/950-1340-mm-numa-Allow-override-of-kernel-s-default-NUMA-poli.patch b/target/linux/bcm27xx/patches-6.6/950-1340-mm-numa-Allow-override-of-kernel-s-default-NUMA-poli.patch new file mode 100644 index 00000000000..f0de0ce9d59 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1340-mm-numa-Allow-override-of-kernel-s-default-NUMA-poli.patch @@ -0,0 +1,115 @@ +From 4bbdd9335a4784743a5ac30697f24972219559c2 Mon Sep 17 00:00:00 2001 +From: Tvrtko Ursulin +Date: Wed, 22 May 2024 17:12:16 +0100 +Subject: [PATCH 1340/1350] mm/numa: Allow override of kernel's default NUMA + policy + +Add numa_policy kernel argument to allow overriding the kernel's default +NUMA policy at boot time. + +Syntax identical to what tmpfs accepts as it's mpol argument is accepted. + +Some examples: + + numa_policy=interleave + numa_policy=interleave=skip-interleave + numa_policy=bind:0-3,5,7,9-15 + numa_policy=bind=static:1-2 + +Signed-off-by: Tvrtko Ursulin +--- + mm/mempolicy.c | 49 ++++++++++++++++++++++++++++++++++++++++++------- + 1 file changed, 42 insertions(+), 7 deletions(-) + +--- a/mm/mempolicy.c ++++ b/mm/mempolicy.c +@@ -2974,7 +2974,9 @@ void __init numa_policy_init(void) + /* Reset policy of current process to default */ + void numa_default_policy(void) + { +- do_set_mempolicy(MPOL_DEFAULT, 0, NULL); ++ struct mempolicy *pol = &default_policy; ++ ++ do_set_mempolicy(pol->mode, pol->flags, &pol->nodes); + } + + /* +@@ -2992,7 +2994,6 @@ static const char * const policy_modes[] + }; + + +-#ifdef CONFIG_TMPFS + /** + * mpol_parse_str - parse string to mempolicy, for tmpfs mpol mount option. + * @str: string containing mempolicy to parse +@@ -3005,13 +3006,18 @@ static const char * const policy_modes[] + */ + int mpol_parse_str(char *str, struct mempolicy **mpol) + { +- struct mempolicy *new = NULL; ++ struct mempolicy *new; + unsigned short mode_flags; + nodemask_t nodes; + char *nodelist = strchr(str, ':'); + char *flags = strchr(str, '='); + int err = 1, mode; + ++ if (*mpol) ++ new = *mpol; ++ else ++ new = NULL; ++ + if (flags) + *flags++ = '\0'; /* terminate mode string */ + +@@ -3090,9 +3096,16 @@ int mpol_parse_str(char *str, struct mem + goto out; + } + +- new = mpol_new(mode, mode_flags, &nodes); +- if (IS_ERR(new)) +- goto out; ++ if (!new) { ++ new = mpol_new(mode, mode_flags, &nodes); ++ if (IS_ERR(new)) ++ goto out; ++ } else { ++ atomic_set(&new->refcnt, 1); ++ new->mode = mode; ++ new->flags = mode_flags; ++ new->home_node = NUMA_NO_NODE; ++ } + + /* + * Save nodes for mpol_to_str() to show the tmpfs mount options +@@ -3125,7 +3138,29 @@ out: + *mpol = new; + return err; + } +-#endif /* CONFIG_TMPFS */ ++ ++static int __init setup_numapolicy(char *str) ++{ ++ struct mempolicy pol = { }, *ppol = &pol; ++ char buf[128]; ++ int ret; ++ ++ if (str) ++ ret = mpol_parse_str(str, &ppol); ++ else ++ ret = -EINVAL; ++ ++ if (!ret) { ++ default_policy = pol; ++ mpol_to_str(buf, sizeof(buf), &pol); ++ pr_info("NUMA default policy overridden to '%s'\n", buf); ++ } else { ++ pr_warn("Unable to parse numa_policy=\n"); ++ } ++ ++ return ret == 0; ++} ++__setup("numa_policy=", setup_numapolicy); + + /** + * mpol_to_str - format a mempolicy structure for printing diff --git a/target/linux/bcm27xx/patches-6.6/950-1341-dma-buf-system_heap-Allow-specifying-maximum-allocat.patch b/target/linux/bcm27xx/patches-6.6/950-1341-dma-buf-system_heap-Allow-specifying-maximum-allocat.patch new file mode 100644 index 00000000000..db2268ea26b --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1341-dma-buf-system_heap-Allow-specifying-maximum-allocat.patch @@ -0,0 +1,46 @@ +From 56fda5adce0c9b4dc8ff2c7be9a704599e685001 Mon Sep 17 00:00:00 2001 +From: Tvrtko Ursulin +Date: Wed, 17 Jul 2024 09:33:21 +0100 +Subject: [PATCH 1341/1350] dma-buf: system_heap: Allow specifying maximum + allocation order + +system_heap.max_order= + +Signed-off-by: Tvrtko Ursulin +--- + drivers/dma-buf/heaps/system_heap.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +--- a/drivers/dma-buf/heaps/system_heap.c ++++ b/drivers/dma-buf/heaps/system_heap.c +@@ -54,6 +54,11 @@ static gfp_t order_flags[] = {HIGH_ORDER + static const unsigned int orders[] = {8, 4, 0}; + #define NUM_ORDERS ARRAY_SIZE(orders) + ++static unsigned int module_max_order = orders[0]; ++ ++module_param_named(max_order, module_max_order, uint, 0400); ++MODULE_PARM_DESC(max_order, "Maximum allocation order override."); ++ + static struct sg_table *dup_sg_table(struct sg_table *table) + { + struct sg_table *new_table; +@@ -339,7 +344,7 @@ static struct dma_buf *system_heap_alloc + struct system_heap_buffer *buffer; + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); + unsigned long size_remaining = len; +- unsigned int max_order = orders[0]; ++ unsigned int max_order = module_max_order; + struct dma_buf *dmabuf; + struct sg_table *table; + struct scatterlist *sg; +@@ -433,6 +438,9 @@ static int system_heap_create(void) + if (IS_ERR(sys_heap)) + return PTR_ERR(sys_heap); + ++ if (module_max_order > orders[0]) ++ module_max_order = orders[0]; ++ + return 0; + } + module_init(system_heap_create); diff --git a/target/linux/bcm27xx/patches-6.6/950-1342-numa-emulation-Check-emulated-zones-around-the-CMA-w.patch b/target/linux/bcm27xx/patches-6.6/950-1342-numa-emulation-Check-emulated-zones-around-the-CMA-w.patch new file mode 100644 index 00000000000..cc459b6a569 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1342-numa-emulation-Check-emulated-zones-around-the-CMA-w.patch @@ -0,0 +1,95 @@ +From a27d76f4517d56a6471def2f76687e83fd2a7923 Mon Sep 17 00:00:00 2001 +From: Tvrtko Ursulin +Date: Mon, 29 Jul 2024 16:53:18 +0100 +Subject: [PATCH 1342/1350] numa/emulation: Check emulated zones around the CMA + window + +... Make sure CMA zones do not straddle the emulated NUMA nodes ... + +Signed-off-by: Tvrtko Ursulin +--- + drivers/base/numa_emulation.c | 5 +++++ + include/linux/cma.h | 10 ++++++++++ + mm/cma.c | 36 +++++++++++++++++++++++++++++++++++ + 3 files changed, 51 insertions(+) + +--- a/drivers/base/numa_emulation.c ++++ b/drivers/base/numa_emulation.c +@@ -7,6 +7,7 @@ + * Author: Maíra Canal + * Author: Tvrtko Ursulin + */ ++#include + #include + + #include "numa_emulation.h" +@@ -55,6 +56,10 @@ int __init numa_emu_init(void) + if (i == (emu_nodes - 1) && e != end) + e = end; + ++ ret = cma_check_range(&s, &e); ++ if (ret) ++ return ret; ++ + pr_info("Faking a node at [mem %pap-%pap]\n", &s, &e); + ret = numa_add_memblk(i, s, e + 1); + if (ret) { +--- a/include/linux/cma.h ++++ b/include/linux/cma.h +@@ -56,4 +56,14 @@ extern bool cma_release(struct cma *cma, + extern int cma_for_each_area(int (*it)(struct cma *cma, void *data), void *data); + + extern void cma_reserve_pages_on_error(struct cma *cma); ++ ++#ifdef CONFIG_CMA ++extern int cma_check_range(u64 *start, u64 *end); ++#else ++static inline int cma_check_range(u64 *start, u64 *end) ++{ ++ return 0; ++} ++#endif ++ + #endif +--- a/mm/cma.c ++++ b/mm/cma.c +@@ -587,3 +587,39 @@ int cma_for_each_area(int (*it)(struct c + + return 0; + } ++ ++struct cma_check_range_data { ++ u64 start, end; ++}; ++ ++static int check_range(struct cma *cma_, void *data) ++{ ++ struct cma_check_range_data *range = data; ++ struct cma_check_range_data cma; ++ bool starts_in_range; ++ bool ends_in_range; ++ ++ cma.start = cma_get_base(cma_); ++ cma.end = cma.start + cma_get_size(cma_) - 1; ++ ++ starts_in_range = cma.start >= range->start && cma.start <= range->end; ++ ends_in_range = cma.end >= range->start && cma.end <= range->end; ++ ++ if (starts_in_range == ends_in_range) ++ return 0; ++ ++ pr_notice("CMA %s [%llx-%llx] straddles range [%llx-%llx]\n", ++ cma_->name, cma.start, cma.end, range->start, range->end); ++ ++ return -EINVAL; ++} ++ ++int cma_check_range(u64 *start, u64 *end) ++{ ++ struct cma_check_range_data range = { ++ .start = *start, ++ .end = *end, ++ }; ++ ++ return cma_for_each_area(check_range, &range); ++} diff --git a/target/linux/bcm27xx/patches-6.6/950-1344-dts-Move-some-common-rpi-settings-into-rpi-files.patch b/target/linux/bcm27xx/patches-6.6/950-1344-dts-Move-some-common-rpi-settings-into-rpi-files.patch new file mode 100644 index 00000000000..26c052c2230 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1344-dts-Move-some-common-rpi-settings-into-rpi-files.patch @@ -0,0 +1,97 @@ +From aece59283a161dfad67c700c2ae97f9dd996eb2f Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 23 Jul 2024 15:55:54 +0100 +Subject: [PATCH 1344/1350] dts: Move some common rpi settings into rpi files + +Most 2711 devices and all 2712 device share common bootargs (command +lines). Make the common values shared defaults, overriding them were +necessary. + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/broadcom/bcm2711-rpi-4-b.dts | 4 ---- + arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4.dts | 4 ---- + arch/arm/boot/dts/broadcom/bcm2711-rpi-ds.dtsi | 1 + + arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts | 5 ----- + arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5.dtsi | 5 ----- + arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi | 5 +++++ + 6 files changed, 6 insertions(+), 18 deletions(-) + +--- a/arch/arm/boot/dts/broadcom/bcm2711-rpi-4-b.dts ++++ b/arch/arm/boot/dts/broadcom/bcm2711-rpi-4-b.dts +@@ -265,10 +265,6 @@ + #include "bcm283x-rpi-i2c0mux_0_44.dtsi" + + / { +- chosen { +- bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_headphones=0"; +- }; +- + /delete-node/ wifi-pwrseq; + }; + +--- a/arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4.dts ++++ b/arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4.dts +@@ -274,10 +274,6 @@ + #include "bcm283x-rpi-i2c0mux_0_44.dtsi" + + / { +- chosen { +- bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_headphones=0"; +- }; +- + /delete-node/ wifi-pwrseq; + }; + +--- a/arch/arm/boot/dts/broadcom/bcm2711-rpi-ds.dtsi ++++ b/arch/arm/boot/dts/broadcom/bcm2711-rpi-ds.dtsi +@@ -3,6 +3,7 @@ + + / { + chosen: chosen { ++ bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_headphones=0"; + }; + + __overrides__ { +--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts ++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts +@@ -432,11 +432,6 @@ dpi_16bit_gpio2: &rp1_dpi_16bit_g + }; + + / { +- chosen: chosen { +- bootargs = "reboot=w coherent_pool=1M 8250.nr_uarts=1 pci=pcie_bus_safe"; +- stdout-path = "serial10:115200n8"; +- }; +- + fan: cooling_fan { + status = "disabled"; + compatible = "pwm-fan"; +--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5.dtsi ++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5.dtsi +@@ -422,11 +422,6 @@ dpi_16bit_gpio2: &rp1_dpi_16bit_g + }; + + / { +- chosen: chosen { +- bootargs = "reboot=w coherent_pool=1M 8250.nr_uarts=1 pci=pcie_bus_safe"; +- stdout-path = "serial10:115200n8"; +- }; +- + fan: cooling_fan { + status = "disabled"; + compatible = "pwm-fan"; +--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi ++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi +@@ -98,6 +98,11 @@ + }; + + / { ++ chosen: chosen { ++ bootargs = "reboot=w coherent_pool=1M 8250.nr_uarts=1 pci=pcie_bus_safe"; ++ stdout-path = "serial10:115200n8"; ++ }; ++ + aliases: aliases { + blconfig = &blconfig; + blpubkey = &blpubkey; diff --git a/target/linux/bcm27xx/patches-6.6/950-1345-dts-Set-preferred-numa-options-in-bootargs.patch b/target/linux/bcm27xx/patches-6.6/950-1345-dts-Set-preferred-numa-options-in-bootargs.patch new file mode 100644 index 00000000000..727c1a3678b --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1345-dts-Set-preferred-numa-options-in-bootargs.patch @@ -0,0 +1,52 @@ +From dd44b93200c412c4c043392243c417f2d70082b3 Mon Sep 17 00:00:00 2001 +From: Dom Cobley +Date: Thu, 18 Jul 2024 20:22:18 +0100 +Subject: [PATCH 1345/1350] dts: Set preferred numa options in bootargs + +The default cmdline adjustment is now numa_policy=interleave for 2711 and 2712, +and additionally system_heap.max_order=0 iommu_dma_numa_policy=interleave for +just 2712 (due to its better iommu support). + +The key setting numa=fake= is not set here, so we will boot with a single +numa region and behaviour should be pretty much unchanged from before this PR. + +Signed-off-by: Dom Cobley +--- + arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4s.dts | 2 +- + arch/arm/boot/dts/broadcom/bcm2711-rpi-ds.dtsi | 2 +- + arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +--- a/arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4s.dts ++++ b/arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4s.dts +@@ -148,7 +148,7 @@ + + / { + chosen { +- bootargs = "coherent_pool=1M snd_bcm2835.enable_headphones=0"; ++ bootargs = "coherent_pool=1M snd_bcm2835.enable_headphones=0 numa_policy=interleave"; + }; + + aliases { +--- a/arch/arm/boot/dts/broadcom/bcm2711-rpi-ds.dtsi ++++ b/arch/arm/boot/dts/broadcom/bcm2711-rpi-ds.dtsi +@@ -3,7 +3,7 @@ + + / { + chosen: chosen { +- bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_headphones=0"; ++ bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_headphones=0 numa_policy=interleave"; + }; + + __overrides__ { +--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi ++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi +@@ -99,7 +99,7 @@ + + / { + chosen: chosen { +- bootargs = "reboot=w coherent_pool=1M 8250.nr_uarts=1 pci=pcie_bus_safe"; ++ bootargs = "reboot=w coherent_pool=1M 8250.nr_uarts=1 pci=pcie_bus_safe numa_policy=interleave iommu_dma_numa_policy=interleave system_heap.max_order=0"; + stdout-path = "serial10:115200n8"; + }; + diff --git a/target/linux/bcm27xx/patches-6.6/950-1346-drm-vc4-Do-not-include-writeback-conn-load-in-load-t.patch b/target/linux/bcm27xx/patches-6.6/950-1346-drm-vc4-Do-not-include-writeback-conn-load-in-load-t.patch new file mode 100644 index 00000000000..1a7c5f64432 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1346-drm-vc4-Do-not-include-writeback-conn-load-in-load-t.patch @@ -0,0 +1,48 @@ +From a2c8327a1b534574d51f5ea42009876e0008efd2 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 9 Sep 2024 17:28:00 +0100 +Subject: [PATCH 1346/1350] drm/vc4: Do not include writeback conn load in load + tracker + +The transposer/writeback connector should be running with a +lower priority, so shouldn't be factored into the load +calculations. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_kms.c | 17 +++++++++++++---- + 1 file changed, 13 insertions(+), 4 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_kms.c +@@ -674,17 +674,26 @@ static int vc4_load_tracker_atomic_check + for_each_oldnew_plane_in_state(state, plane, old_plane_state, + new_plane_state, i) { + struct vc4_plane_state *vc4_plane_state; ++ struct vc4_crtc *vc4_crtc; + + if (old_plane_state->fb && old_plane_state->crtc) { + vc4_plane_state = to_vc4_plane_state(old_plane_state); +- load_state->membus_load -= vc4_plane_state->membus_load; +- load_state->hvs_load -= vc4_plane_state->hvs_load; ++ vc4_crtc = to_vc4_crtc(old_plane_state->crtc); ++ ++ if (!vc4_crtc->feeds_txp) { ++ load_state->membus_load -= vc4_plane_state->membus_load; ++ load_state->hvs_load -= vc4_plane_state->hvs_load; ++ } + } + + if (new_plane_state->fb && new_plane_state->crtc) { + vc4_plane_state = to_vc4_plane_state(new_plane_state); +- load_state->membus_load += vc4_plane_state->membus_load; +- load_state->hvs_load += vc4_plane_state->hvs_load; ++ vc4_crtc = to_vc4_crtc(new_plane_state->crtc); ++ ++ if (!vc4_crtc->feeds_txp) { ++ load_state->membus_load += vc4_plane_state->membus_load; ++ load_state->hvs_load += vc4_plane_state->hvs_load; ++ } + } + } + diff --git a/target/linux/bcm27xx/patches-6.6/950-1347-drm-vc4-Drop-panic-priority-for-writeback-connector.patch b/target/linux/bcm27xx/patches-6.6/950-1347-drm-vc4-Drop-panic-priority-for-writeback-connector.patch new file mode 100644 index 00000000000..91187d20cb3 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1347-drm-vc4-Drop-panic-priority-for-writeback-connector.patch @@ -0,0 +1,54 @@ +From 2e85eb0e4950c5ad27df5a3ba54300e89694eba4 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 9 Sep 2024 17:38:45 +0100 +Subject: [PATCH 1347/1350] drm/vc4: Drop panic priority for writeback + connector + +As the writeback connector doesn't have the same realtime +constraints of a live display, drop the panic priority for it. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_kms.c | 21 ++++++++++++++------- + 1 file changed, 14 insertions(+), 7 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_kms.c +@@ -224,7 +224,7 @@ static void vc4_hvs_pv_muxing_commit(str + struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); + struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc_state); + u32 dispctrl; +- u32 dsp3_mux; ++ u32 dsp3_mux_pri; + + if (!crtc_state->active) + continue; +@@ -241,15 +241,22 @@ static void vc4_hvs_pv_muxing_commit(str + * enabled. In this case, FIFO 2 is directly accessed by the + * TXP IP, and we need to disable the FIFO2 -> pixelvalve1 + * route. ++ * ++ * TXP can also run with a lower panic level than a live display, ++ * as it doesn't have the same real-time constraint. + */ +- if (vc4_crtc->feeds_txp) +- dsp3_mux = VC4_SET_FIELD(3, SCALER_DISPCTRL_DSP3_MUX); +- else +- dsp3_mux = VC4_SET_FIELD(2, SCALER_DISPCTRL_DSP3_MUX); ++ if (vc4_crtc->feeds_txp) { ++ dsp3_mux_pri = VC4_SET_FIELD(3, SCALER_DISPCTRL_DSP3_MUX); ++ dsp3_mux_pri |= VC4_SET_FIELD(0, SCALER_DISPCTRL_PANIC2); ++ } else { ++ dsp3_mux_pri = VC4_SET_FIELD(2, SCALER_DISPCTRL_DSP3_MUX); ++ dsp3_mux_pri |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC2); ++ } + + dispctrl = HVS_READ(SCALER_DISPCTRL) & +- ~SCALER_DISPCTRL_DSP3_MUX_MASK; +- HVS_WRITE(SCALER_DISPCTRL, dispctrl | dsp3_mux); ++ ~(SCALER_DISPCTRL_DSP3_MUX_MASK | ++ SCALER_DISPCTRL_PANIC2_MASK); ++ HVS_WRITE(SCALER_DISPCTRL, dispctrl | dsp3_mux_pri); + } + } + diff --git a/target/linux/bcm27xx/patches-6.6/950-1348-dts-Simplify-bootargs.patch b/target/linux/bcm27xx/patches-6.6/950-1348-dts-Simplify-bootargs.patch new file mode 100644 index 00000000000..f6de5994d63 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1348-dts-Simplify-bootargs.patch @@ -0,0 +1,112 @@ +From 8334494807ff5de7e500cb22e078c08754341c26 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Fri, 25 Oct 2024 10:36:20 +0100 +Subject: [PATCH 1348/1350] dts: Simplify bootargs + +Reduce the number of different places that bootargs is set in Pi dts +files. The variants are all combinations of with/without Bluetooth +and with/without NUMA support (2711). + +This is effectively a cosmetic change - the resulting dtbs are +unchanged. + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/broadcom/bcm2708-rpi-bt.dtsi | 4 ++++ + arch/arm/boot/dts/broadcom/bcm2708-rpi-zero-w.dts | 4 ---- + arch/arm/boot/dts/broadcom/bcm2710-rpi-3-b-plus.dts | 4 ---- + arch/arm/boot/dts/broadcom/bcm2710-rpi-3-b.dts | 4 ---- + arch/arm/boot/dts/broadcom/bcm2710-rpi-zero-2-w.dts | 4 ---- + arch/arm/boot/dts/broadcom/bcm2711-rpi-ds.dtsi | 2 +- + arch/arm/boot/dts/broadcom/bcm271x-rpi-bt.dtsi | 4 ++++ + 7 files changed, 9 insertions(+), 17 deletions(-) + +--- a/arch/arm/boot/dts/broadcom/bcm2708-rpi-bt.dtsi ++++ b/arch/arm/boot/dts/broadcom/bcm2708-rpi-bt.dtsi +@@ -23,6 +23,10 @@ + }; + + / { ++ chosen { ++ bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_headphones=0"; ++ }; ++ + aliases { + bluetooth = &bt; + }; +--- a/arch/arm/boot/dts/broadcom/bcm2708-rpi-zero-w.dts ++++ b/arch/arm/boot/dts/broadcom/bcm2708-rpi-zero-w.dts +@@ -11,10 +11,6 @@ + compatible = "raspberrypi,model-zero-w", "brcm,bcm2835"; + model = "Raspberry Pi Zero W"; + +- chosen { +- bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_headphones=0"; +- }; +- + aliases { + serial0 = &uart1; + serial1 = &uart0; +--- a/arch/arm/boot/dts/broadcom/bcm2710-rpi-3-b-plus.dts ++++ b/arch/arm/boot/dts/broadcom/bcm2710-rpi-3-b-plus.dts +@@ -12,10 +12,6 @@ + compatible = "raspberrypi,3-model-b-plus", "brcm,bcm2837"; + model = "Raspberry Pi 3 Model B+"; + +- chosen { +- bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_headphones=0"; +- }; +- + aliases { + serial0 = &uart1; + serial1 = &uart0; +--- a/arch/arm/boot/dts/broadcom/bcm2710-rpi-3-b.dts ++++ b/arch/arm/boot/dts/broadcom/bcm2710-rpi-3-b.dts +@@ -12,10 +12,6 @@ + compatible = "raspberrypi,3-model-b", "brcm,bcm2837"; + model = "Raspberry Pi 3 Model B"; + +- chosen { +- bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_headphones=0"; +- }; +- + aliases { + serial0 = &uart1; + serial1 = &uart0; +--- a/arch/arm/boot/dts/broadcom/bcm2710-rpi-zero-2-w.dts ++++ b/arch/arm/boot/dts/broadcom/bcm2710-rpi-zero-2-w.dts +@@ -11,10 +11,6 @@ + compatible = "raspberrypi,model-zero-2-w", "brcm,bcm2837"; + model = "Raspberry Pi Zero 2 W"; + +- chosen { +- bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_headphones=0"; +- }; +- + aliases { + serial0 = &uart1; + serial1 = &uart0; +--- a/arch/arm/boot/dts/broadcom/bcm2711-rpi-ds.dtsi ++++ b/arch/arm/boot/dts/broadcom/bcm2711-rpi-ds.dtsi +@@ -2,7 +2,7 @@ + #include "bcm270x-rpi.dtsi" + + / { +- chosen: chosen { ++ chosen { + bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_headphones=0 numa_policy=interleave"; + }; + +--- a/arch/arm/boot/dts/broadcom/bcm271x-rpi-bt.dtsi ++++ b/arch/arm/boot/dts/broadcom/bcm271x-rpi-bt.dtsi +@@ -23,6 +23,10 @@ + }; + + / { ++ chosen { ++ bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_headphones=0"; ++ }; ++ + aliases { + bluetooth = &bt; + }; diff --git a/target/linux/bcm27xx/patches-6.6/950-1349-cgroup-Use-kernel-command-line-to-disable-memory-cgr.patch b/target/linux/bcm27xx/patches-6.6/950-1349-cgroup-Use-kernel-command-line-to-disable-memory-cgr.patch new file mode 100644 index 00000000000..46e0aeaf4ce --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1349-cgroup-Use-kernel-command-line-to-disable-memory-cgr.patch @@ -0,0 +1,193 @@ +From 86099deff5abf5f63643eecaedb4c11ae77474ce Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ma=C3=ADra=20Canal?= +Date: Thu, 24 Oct 2024 08:03:19 -0300 +Subject: [PATCH 1349/1350] cgroup: Use kernel command line to disable memory + cgroup +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Commit 94a23e978235 ("cgroup: Disable cgroup "memory" by default") +disabled the memory cgroup by default when initing the cgroups. However, +it's possible to disable the memory cgroup by a kernel command line. +Hard-coding such a feature can be problematic as some memory management +features depend on the order that things are set. + +For example, it is possible to see a NULL pointer dereference caused by +commit 94a23e978235cd35f38075072b34152b2b667e6e. The NULL pointer +dereference is triggered by the memory shrinker and ends up in a kernel +crash. + +[ 50.028629] ================================================================== +[ 50.028645] BUG: KASAN: null-ptr-deref in do_shrink_slab+0x1fc/0x978 +[ 50.028663] Write of size 8 at addr 0000000000000000 by task gfxrecon-replay/1965 + +[ 50.028676] CPU: 3 UID: 1000 PID: 1965 Comm: gfxrecon-replay Tainted: G C 6.12.0-rc4-v8-thp-kasan+ #85 +[ 50.028685] Tainted: [C]=CRAP +[ 50.028689] Hardware name: Raspberry Pi 5 Model B Rev 1.0 (DT) +[ 50.028694] Call trace: +[ 50.028697] dump_backtrace+0xfc/0x120 +[ 50.028706] show_stack+0x24/0x38 +[ 50.028711] dump_stack_lvl+0x40/0x88 +[ 50.028720] print_report+0xe4/0x708 +[ 50.028728] kasan_report+0xcc/0x130 +[ 50.028733] kasan_check_range+0x254/0x298 +[ 50.028738] __kasan_check_write+0x20/0x30 +[ 50.028745] do_shrink_slab+0x1fc/0x978 +[ 50.028751] shrink_slab+0x318/0xc38 +[ 50.028756] shrink_one+0x254/0x6d8 +[ 50.028762] shrink_node+0x26b4/0x2848 +[ 50.028767] do_try_to_free_pages+0x3e4/0x1190 +[ 50.028773] try_to_free_pages+0x5a4/0xb40 +[ 50.028778] __alloc_pages_direct_reclaim+0x144/0x298 +[ 50.028787] __alloc_pages_slowpath+0x5c4/0xc70 +[ 50.028793] __alloc_pages_noprof+0x4a8/0x6a8 +[ 50.028800] __folio_alloc_noprof+0x24/0xa8 +[ 50.028806] shmem_alloc_and_add_folio+0x2ec/0xce0 +[ 50.028812] shmem_get_folio_gfp+0x380/0xc20 +[ 50.028818] shmem_read_folio_gfp+0xe0/0x160 +[ 50.028824] drm_gem_get_pages+0x238/0x620 [drm] +[ 50.029039] drm_gem_shmem_get_pages_sgt+0xd8/0x4b8 [drm_shmem_helper] +[ 50.029053] v3d_bo_create_finish+0x58/0x1e0 [v3d] +[ 50.029083] v3d_create_bo_ioctl+0xac/0x210 [v3d] +[ 50.029105] drm_ioctl_kernel+0x1d8/0x2b8 [drm] +[ 50.029220] drm_ioctl+0x4b4/0x920 [drm] +[ 50.029330] __arm64_sys_ioctl+0x11c/0x160 +[ 50.029337] invoke_syscall+0x88/0x268 +[ 50.029345] el0_svc_common+0x160/0x1d8 +[ 50.029351] do_el0_svc+0x50/0x68 +[ 50.029358] el0_svc+0x34/0x80 +[ 50.029364] el0t_64_sync_handler+0x84/0x100 +[ 50.029371] el0t_64_sync+0x190/0x198 +[ 50.029376] ================================================================== + +This happens because the memory shrinker is unaware that we are +artificially disabling the memory cgroups and therefore it doesn't +allocate `nr_deferred` (as it would if we used the kernel command line). + +To avoid such an issue, revert the artificial disablement and disable it +through the command line. If a user wants to enable the feature, it can +use the `cgroup_enable=` command line. + +Signed-off-by: Maíra Canal +--- + arch/arm/boot/dts/broadcom/bcm2708-rpi-bt.dtsi | 2 +- + arch/arm/boot/dts/broadcom/bcm270x.dtsi | 2 +- + arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4s.dts | 2 +- + arch/arm/boot/dts/broadcom/bcm2711-rpi-ds.dtsi | 2 +- + arch/arm/boot/dts/broadcom/bcm271x-rpi-bt.dtsi | 2 +- + arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi | 2 +- + kernel/cgroup/cgroup.c | 15 +-------------- + 7 files changed, 7 insertions(+), 20 deletions(-) + +--- a/arch/arm/boot/dts/broadcom/bcm2708-rpi-bt.dtsi ++++ b/arch/arm/boot/dts/broadcom/bcm2708-rpi-bt.dtsi +@@ -24,7 +24,7 @@ + + / { + chosen { +- bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_headphones=0"; ++ bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_headphones=0 cgroup_disable=memory"; + }; + + aliases { +--- a/arch/arm/boot/dts/broadcom/bcm270x.dtsi ++++ b/arch/arm/boot/dts/broadcom/bcm270x.dtsi +@@ -4,7 +4,7 @@ + / { + chosen: chosen { + // Disable audio by default +- bootargs = "coherent_pool=1M snd_bcm2835.enable_headphones=0"; ++ bootargs = "coherent_pool=1M snd_bcm2835.enable_headphones=0 cgroup_disable=memory"; + stdout-path = "serial0:115200n8"; + }; + +--- a/arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4s.dts ++++ b/arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4s.dts +@@ -148,7 +148,7 @@ + + / { + chosen { +- bootargs = "coherent_pool=1M snd_bcm2835.enable_headphones=0 numa_policy=interleave"; ++ bootargs = "coherent_pool=1M snd_bcm2835.enable_headphones=0 cgroup_disable=memory numa_policy=interleave"; + }; + + aliases { +--- a/arch/arm/boot/dts/broadcom/bcm2711-rpi-ds.dtsi ++++ b/arch/arm/boot/dts/broadcom/bcm2711-rpi-ds.dtsi +@@ -3,7 +3,7 @@ + + / { + chosen { +- bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_headphones=0 numa_policy=interleave"; ++ bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_headphones=0 cgroup_disable=memory numa_policy=interleave"; + }; + + __overrides__ { +--- a/arch/arm/boot/dts/broadcom/bcm271x-rpi-bt.dtsi ++++ b/arch/arm/boot/dts/broadcom/bcm271x-rpi-bt.dtsi +@@ -24,7 +24,7 @@ + + / { + chosen { +- bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_headphones=0"; ++ bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_headphones=0 cgroup_disable=memory"; + }; + + aliases { +--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi ++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi +@@ -99,7 +99,7 @@ + + / { + chosen: chosen { +- bootargs = "reboot=w coherent_pool=1M 8250.nr_uarts=1 pci=pcie_bus_safe numa_policy=interleave iommu_dma_numa_policy=interleave system_heap.max_order=0"; ++ bootargs = "reboot=w coherent_pool=1M 8250.nr_uarts=1 pci=pcie_bus_safe cgroup_disable=memory numa_policy=interleave iommu_dma_numa_policy=interleave system_heap.max_order=0"; + stdout-path = "serial10:115200n8"; + }; + +--- a/kernel/cgroup/cgroup.c ++++ b/kernel/cgroup/cgroup.c +@@ -6060,9 +6060,6 @@ int __init cgroup_init_early(void) + return 0; + } + +-static u16 cgroup_enable_mask __initdata; +-static int __init cgroup_disable(char *str); +- + /** + * cgroup_init - cgroup initialization + * +@@ -6096,12 +6093,6 @@ int __init cgroup_init(void) + + cgroup_unlock(); + +- /* +- * Apply an implicit disable, knowing that an explicit enable will +- * prevent if from doing anything. +- */ +- cgroup_disable("memory"); +- + for_each_subsys(ss, ssid) { + if (ss->early_init) { + struct cgroup_subsys_state *css = +@@ -6742,10 +6733,6 @@ static int __init cgroup_disable(char *s + strcmp(token, ss->legacy_name)) + continue; + +- /* An explicit cgroup_enable overrides a disable */ +- if (cgroup_enable_mask & (1 << i)) +- continue; +- + static_branch_disable(cgroup_subsys_enabled_key[i]); + pr_info("Disabling %s control group subsystem\n", + ss->name); +@@ -6779,7 +6766,7 @@ static int __init cgroup_enable(char *st + strcmp(token, ss->legacy_name)) + continue; + +- cgroup_enable_mask |= 1 << i; ++ cgroup_feature_disable_mask &= ~(1 << i); + static_branch_enable(cgroup_subsys_enabled_key[i]); + pr_info("Enabling %s control group subsystem\n", + ss->name); diff --git a/target/linux/bcm27xx/patches-6.6/950-1350-arm64-dts-Sort-out-CM5-and-I-O-board-I2C-ports.patch b/target/linux/bcm27xx/patches-6.6/950-1350-arm64-dts-Sort-out-CM5-and-I-O-board-I2C-ports.patch new file mode 100644 index 00000000000..8ee3b754643 --- /dev/null +++ b/target/linux/bcm27xx/patches-6.6/950-1350-arm64-dts-Sort-out-CM5-and-I-O-board-I2C-ports.patch @@ -0,0 +1,185 @@ +From 4622323f5c9e540f3356f2229c4d551b31cc234d Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Thu, 24 Oct 2024 15:38:36 +0100 +Subject: [PATCH 1350/1350] arm64: dts: Sort out CM5 and I/O board I2C ports + +There is a difference in I2C usage between CM4IO and CM5IO. Present a +simple, consistent view of the world by moving the assignment of the +bus IDs into carrier-specific files. + +CM5 has reduced connectivity on CM4IO - the DPHYs are connected to +CAM1 and DISP1. Keep i2c-10 for use with that pair, as is the case for +CM4 on CM4IO. + +Fixes: 36faab69e8ee ("dts: bcm2712-rpi: Add aliases for the CSI/DSI I2Cs") +See: https://github.com/raspberrypi/linux/pull/6421 + +Signed-off-by: Phil Elwell +--- + .../boot/dts/broadcom/bcm2712-rpi-cm4io.dtsi | 28 +++++++++++++++++++ + .../dts/broadcom/bcm2712-rpi-cm5-cm4io.dts | 17 +---------- + .../dts/broadcom/bcm2712-rpi-cm5-cm5io.dts | 7 +---- + .../boot/dts/broadcom/bcm2712-rpi-cm5.dtsi | 13 --------- + .../boot/dts/broadcom/bcm2712-rpi-cm5io.dtsi | 14 ++++++++++ + .../dts/broadcom/bcm2712-rpi-cm5l-cm4io.dts | 17 +---------- + .../dts/broadcom/bcm2712-rpi-cm5l-cm5io.dts | 7 +---- + .../boot/dts/broadcom/bcm2712-rpi-cm5l.dtsi | 4 --- + 8 files changed, 46 insertions(+), 61 deletions(-) + create mode 100644 arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm4io.dtsi + create mode 100644 arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5io.dtsi + +--- /dev/null ++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm4io.dtsi +@@ -0,0 +1,28 @@ ++// SPDX-License-Identifier: GPL-2.0 ++ ++i2c_csi_dsi0: &i2c0 { // Note: For CAM0 and DISP0 connectors ++}; ++ ++i2c_csi_dsi1: &i2c6 { // Note: For CAM1, DISP1, on-board RTC, and fan controller ++ pinctrl-0 = <&rp1_i2c6_38_39>; ++ pinctrl-names = "default"; ++ clock-frequency = <100000>; ++ symlink = "i2c-6"; ++}; ++ ++i2c_csi_dsi: &i2c_csi_dsi1 { }; // The connector that needs no jumper to enable ++ ++&aliases { ++ /delete-property/ i2c11; ++ i2c10 = &i2c_csi_dsi; ++}; ++ ++// The RP1 USB3 interfaces are not usable on CM4IO ++ ++&rp1_usb0 { ++ status = "disabled"; ++}; ++ ++&rp1_usb1 { ++ status = "disabled"; ++}; +--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5-cm4io.dts ++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5-cm4io.dts +@@ -2,19 +2,4 @@ + /dts-v1/; + + #include "bcm2712-rpi-cm5.dtsi" +- +-// The RP1 USB3 interfaces are not usable on CM4IO +- +-&rp1_usb0 { +- status = "disabled"; +-}; +- +-&rp1_usb1 { +- status = "disabled"; +-}; +- +-/ { +- __overrides__ { +- i2c_csi_dsi = <&i2c_csi_dsi>, "status"; +- }; +-}; ++#include "bcm2712-rpi-cm4io.dtsi" +--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5-cm5io.dts ++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5-cm5io.dts +@@ -2,9 +2,4 @@ + /dts-v1/; + + #include "bcm2712-rpi-cm5.dtsi" +- +-/ { +- __overrides__ { +- i2c_csi_dsi = <&i2c_csi_dsi>, "status"; +- }; +-}; ++#include "bcm2712-rpi-cm5io.dtsi" +--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5.dtsi ++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5.dtsi +@@ -234,19 +234,6 @@ aux: &dummy {}; + + #include "bcm2712-rpi.dtsi" + +-i2c_csi_dsi0: &i2c6 { // Note: This is for MIPI0 connector only +- pinctrl-0 = <&rp1_i2c6_38_39>; +- pinctrl-names = "default"; +- clock-frequency = <100000>; +- symlink = "i2c-6"; +-}; +- +-i2c_csi_dsi1: &i2c0 { // Note: This is for MIPI1 connector +- symlink = "i2c-11"; +-}; +- +-i2c_csi_dsi: &i2c_csi_dsi1 { }; // An alias for compatibility +- + cam1_reg: &cam0_reg { // Shares CAM_GPIO with cam0_reg + }; + +--- /dev/null ++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5io.dtsi +@@ -0,0 +1,14 @@ ++// SPDX-License-Identifier: GPL-2.0 ++ ++i2c_csi_dsi1: &i2c0 { // Note: This is for CAM/DISP 1 connector ++ symlink = "i2c-11"; ++}; ++ ++i2c_csi_dsi0: &i2c6 { // Note: This is for CAM/DISP 0 connector ++ pinctrl-0 = <&rp1_i2c6_38_39>; ++ pinctrl-names = "default"; ++ clock-frequency = <100000>; ++ symlink = "i2c-6"; ++}; ++ ++i2c_csi_dsi: &i2c_csi_dsi0 { }; // The connector that needs no jumper to enable +--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5l-cm4io.dts ++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5l-cm4io.dts +@@ -2,19 +2,4 @@ + /dts-v1/; + + #include "bcm2712-rpi-cm5l.dtsi" +- +-// The RP1 USB3 interfaces are not usable on CM4IO +- +-&rp1_usb0 { +- status = "disabled"; +-}; +- +-&rp1_usb1 { +- status = "disabled"; +-}; +- +-/ { +- __overrides__ { +- i2c_csi_dsi = <&i2c_csi_dsi>, "status"; +- }; +-}; ++#include "bcm2712-rpi-cm4io.dtsi" +--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5l-cm5io.dts ++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5l-cm5io.dts +@@ -2,9 +2,4 @@ + /dts-v1/; + + #include "bcm2712-rpi-cm5l.dtsi" +- +-/ { +- __overrides__ { +- i2c_csi_dsi = <&i2c_csi_dsi>, "status"; +- }; +-}; ++#include "bcm2712-rpi-cm5io.dtsi" +--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5l.dtsi ++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5l.dtsi +@@ -5,10 +5,6 @@ + + / { + model = "Raspberry Pi Compute Module 5 Lite"; +- +- __overrides__ { +- i2c_csi_dsi = <&i2c_csi_dsi>, "status"; +- }; + }; + + &sd_io_1v8_reg { From fc236f3b3c54953805173e5ab571f794eb5ff398 Mon Sep 17 00:00:00 2001 From: Lech Perczak Date: Thu, 24 Oct 2024 20:51:00 +0200 Subject: [PATCH 19/27] ath79: Really fix 5GHz on QCA9886 variant of ZTE MF286 Fix in commit 25eead21c5ab ("ath79: fix 5GHz on QCA9886 variant of ZTE MF286") was incomplete. A user of such variant popped up, and in the boot log after installation, we discovered that QCA9886 expects different pre-calibration data size, than the older QCA9880 variant: ath10k_pci 0000:00:00.0: qca9888 hw2.0 target 0x01000000 chip_id 0x00000000 sub 0000:0000 ath10k_pci 0000:00:00.0: kconfig debug 0 debugfs 1 tracing 0 dfs 1 testmode 0 ath10k_pci 0000:00:00.0: firmware ver 10.4b-ct-9888-fW-13-5ae337bb1 api 5 features mfp,peer-flow-ctrl,txstatus-noack,wmi-10.x-CT,ratemask-CT,regdump-CT,txrate-CT,flush-all-CT,pingpong-CT,ch-regs-CT,nop-CT,set-special-CT,tx-rc-CT,cust-stats-CT,txrate2-CT,beacon-cb-CT,wmi-block-ack-CT,wmi-bcn-rc-CT crc32 59e741e7 ath10k_pci 0000:00:00.0: invalid calibration data length in nvmem-cell 'pre-calibration': 2116 != 12064 ath10k_pci 0000:00:00.0: Loading BDF type 0 ath10k_pci 0000:00:00.0: failed to fetch board data for bus=pci,vendor=168c,device=0056,subsystem-vendor=0000,subsystem-device=0000 from ath10k/QCA9888/hw2.0/board-2.bin ath10k_pci 0000:00:00.0: failed to fetch board-2.bin or board.bin from ath10k/QCA9888/hw2.0 ath10k_pci 0000:00:00.0: failed to fetch board file: -12 ath10k_pci 0000:00:00.0: could not probe fw (-12) Explicitly define a pre-calibration nvmem-cell for this variant, and use it instead of the calibration one, which is shorter. Fixes: 25eead21c5ab ("ath79: fix 5GHz on QCA9886 variant of ZTE MF286") Signed-off-by: Lech Perczak Link: https://github.com/openwrt/openwrt/pull/16809 Signed-off-by: Hauke Mehrtens --- target/linux/ath79/dts/qca9563_zte_mf286.dts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/target/linux/ath79/dts/qca9563_zte_mf286.dts b/target/linux/ath79/dts/qca9563_zte_mf286.dts index 4b922396661..897ecf66ea8 100644 --- a/target/linux/ath79/dts/qca9563_zte_mf286.dts +++ b/target/linux/ath79/dts/qca9563_zte_mf286.dts @@ -70,13 +70,20 @@ #address-cells = <1>; #size-cells = <1>; + /* ath9k */ cal_caldata_1000: cal@1000 { reg = <0x1000 0x440>; }; + /* ath10k wave1 in plain MF286 */ cal_caldata_5000: cal@5000 { reg = <0x5000 0x844>; }; + + /* ath10k wave2 in early MF286A */ + precal_caldata_5000: precal@5000 { + reg = <0x5000 0x2f20>; + }; }; }; @@ -128,7 +135,7 @@ }; &wifi_ath10k { - nvmem-cells = <&macaddr_mac_0 1>, <&cal_caldata_5000>, <&cal_caldata_5000>; + nvmem-cells = <&macaddr_mac_0 1>, <&cal_caldata_5000>, <&precal_caldata_5000>; nvmem-cell-names = "mac-address", "calibration", "pre-calibration"; }; From 2b173ab730897f53539cab39e87e2b4638cb482a Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Fri, 1 Nov 2024 03:37:51 +0000 Subject: [PATCH 20/27] mediatek: mt7988: fix peripheral SPI busses The clocks for SPI busses were named wrongly which resulted in the spi-mt65xx driver not requesting them. This has apparently been worked around by marking the clocks required for SPI0 which is used for SPI-NOR and SPI-NAND flash chips as critical. Fix the device tree for all 3 generic SPI host controllers and no longer mark clocks as critical. Signed-off-by: Daniel Golle --- .../arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 8 +-- ...nfracfg-SPI0-clocks-are-not-critical.patch | 65 +++++++++++++++++++ 2 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 target/linux/mediatek/patches-6.6/255-clk-mediatek-mt7988-infracfg-SPI0-clocks-are-not-critical.patch diff --git a/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7988a.dtsi index c894253fedd..39f8fd2ab14 100644 --- a/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7988a.dtsi +++ b/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7988a.dtsi @@ -806,7 +806,7 @@ <&infracfg CLK_INFRA_104M_SPI0>, <&infracfg CLK_INFRA_66M_SPI0_HCK>; clock-names = "parent-clk", "sel-clk", "spi-clk", - "spi-hclk"; + "hclk"; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -817,11 +817,11 @@ reg = <0 0x11008000 0 0x100>; interrupts = ; clocks = <&topckgen CLK_TOP_MPLL_D2>, - <&topckgen CLK_TOP_SPI_SEL>, + <&topckgen CLK_TOP_SPIM_MST_SEL>, <&infracfg CLK_INFRA_104M_SPI1>, <&infracfg CLK_INFRA_66M_SPI1_HCK>; clock-names = "parent-clk", "sel-clk", "spi-clk", - "spi-hclk"; + "hclk"; #address-cells = <1>; #size-cells = <0>; pinctrl-names = "default"; @@ -838,7 +838,7 @@ <&infracfg CLK_INFRA_104M_SPI2_BCK>, <&infracfg CLK_INFRA_66M_SPI2_HCK>; clock-names = "parent-clk", "sel-clk", "spi-clk", - "spi-hclk"; + "hclk"; #address-cells = <1>; #size-cells = <0>; status = "disabled"; diff --git a/target/linux/mediatek/patches-6.6/255-clk-mediatek-mt7988-infracfg-SPI0-clocks-are-not-critical.patch b/target/linux/mediatek/patches-6.6/255-clk-mediatek-mt7988-infracfg-SPI0-clocks-are-not-critical.patch new file mode 100644 index 00000000000..ed3471933c4 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/255-clk-mediatek-mt7988-infracfg-SPI0-clocks-are-not-critical.patch @@ -0,0 +1,65 @@ +From patchwork Fri Nov 1 03:19:39 2024 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Daniel Golle +X-Patchwork-Id: 13858671 +Return-Path: + +Date: Fri, 1 Nov 2024 03:19:39 +0000 +From: Daniel Golle +To: linux-mediatek@lists.infradead.org, linux-arm-kernel@lists.infradead.org, + linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, Uwe + =?iso-8859-1?q?Kleine-K=F6nig?= , + Sam Shih , Frank Wunderlich , + Daniel Golle , + AngeloGioacchino Del Regno , + Matthias Brugger , Stephen Boyd , + Michael Turquette +Subject: [PATCH] clk: mediatek: mt7988-infracfg: SPI0 clocks are not critical +Message-ID: +MIME-Version: 1.0 +Content-Disposition: inline +X-BeenThere: linux-mediatek@lists.infradead.org +X-Mailman-Version: 2.1.34 +Precedence: list +List-Id: +List-Unsubscribe: , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: , + +Sender: "Linux-mediatek" +Errors-To: + linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org + +SPI0 clocks have wrongly been marked as critical while, probably due +to the SPI driver not requesting them. This can (and should) be addressed +in device tree instead. +Remove CLK_IS_CRITICAL flag from clocks related to SPI0. + +Fixes: 4b4719437d85 ("clk: mediatek: add drivers for MT7988 SoC") +Signed-off-by: Daniel Golle +--- + drivers/clk/mediatek/clk-mt7988-infracfg.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +--- a/drivers/clk/mediatek/clk-mt7988-infracfg.c ++++ b/drivers/clk/mediatek/clk-mt7988-infracfg.c +@@ -196,12 +196,10 @@ static const struct mtk_gate infra_clks[ + GATE_INFRA2(CLK_INFRA_SPINFI, "infra_f_fspinfi", "spinfi_sel", 10), + GATE_INFRA2_FLAGS(CLK_INFRA_66M_NFI_HCK, "infra_hf_66m_nfi_hck", "sysaxi_sel", 11, + CLK_IS_CRITICAL), +- GATE_INFRA2_FLAGS(CLK_INFRA_104M_SPI0, "infra_hf_104m_spi0", "infra_mux_spi0_sel", 12, +- CLK_IS_CRITICAL), ++ GATE_INFRA2(CLK_INFRA_104M_SPI0, "infra_hf_104m_spi0", "infra_mux_spi0_sel", 12), + GATE_INFRA2(CLK_INFRA_104M_SPI1, "infra_hf_104m_spi1", "infra_mux_spi1_sel", 13), + GATE_INFRA2(CLK_INFRA_104M_SPI2_BCK, "infra_hf_104m_spi2_bck", "infra_mux_spi2_sel", 14), +- GATE_INFRA2_FLAGS(CLK_INFRA_66M_SPI0_HCK, "infra_hf_66m_spi0_hck", "sysaxi_sel", 15, +- CLK_IS_CRITICAL), ++ GATE_INFRA2(CLK_INFRA_66M_SPI0_HCK, "infra_hf_66m_spi0_hck", "sysaxi_sel", 15), + GATE_INFRA2(CLK_INFRA_66M_SPI1_HCK, "infra_hf_66m_spi1_hck", "sysaxi_sel", 16), + GATE_INFRA2(CLK_INFRA_66M_SPI2_HCK, "infra_hf_66m_spi2_hck", "sysaxi_sel", 17), + GATE_INFRA2(CLK_INFRA_66M_FLASHIF_AXI, "infra_hf_66m_flashif_axi", "sysaxi_sel", 18), From a535cfc09e1ced5785d65bee0a0116a71585128e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20=C5=A0tetiar?= Date: Fri, 1 Nov 2024 06:25:07 +0000 Subject: [PATCH 21/27] openwrt-keyring: add OpenWrt 24.10 release build usign key MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fbae29d730f8 usign: add OpenWrt 24.10 release build public key Signed-off-by: Petr Štetiar --- package/system/openwrt-keyring/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package/system/openwrt-keyring/Makefile b/package/system/openwrt-keyring/Makefile index 9344ec321d9..029463817b8 100644 --- a/package/system/openwrt-keyring/Makefile +++ b/package/system/openwrt-keyring/Makefile @@ -7,9 +7,9 @@ PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/keyring.git -PKG_SOURCE_DATE:=2024-09-28 -PKG_SOURCE_VERSION:=3c066ce24e80d8f537d582406930d60c7cafb251 -PKG_MIRROR_HASH:=27a52fd164d38cc57d052e0e04c95ac941ce90be6231c2eb85dcbbde9d3b916e +PKG_SOURCE_DATE:=2024-11-01 +PKG_SOURCE_VERSION:=fbae29d730f81c892f52e0ff00fe867444aeeae6 +PKG_MIRROR_HASH:=9a314756ddb61dde084f810ef056835addd9097ad26cb5e66efc6b38debc8aa0 PKG_MAINTAINER:=John Crispin PKG_LICENSE:=GPL-2.0 From 88fa1f7b1e07c4dda3a9e387a4094ad8a06fcf0c Mon Sep 17 00:00:00 2001 From: John Crispin Date: Sat, 21 Sep 2024 09:47:26 +0200 Subject: [PATCH 22/27] uboot-mediatek: add support for arcadyan,mozart Signed-off-by: John Crispin --- package/boot/uboot-mediatek/Makefile | 13 + .../patches/456-add-arcadyan-mozart.patch | 308 ++++++++++++++++++ 2 files changed, 321 insertions(+) create mode 100644 package/boot/uboot-mediatek/patches/456-add-arcadyan-mozart.patch diff --git a/package/boot/uboot-mediatek/Makefile b/package/boot/uboot-mediatek/Makefile index e5a0a393fe5..62979724c2e 100644 --- a/package/boot/uboot-mediatek/Makefile +++ b/package/boot/uboot-mediatek/Makefile @@ -629,6 +629,18 @@ define U-Boot/mt7986_zyxel_ex5601-t0 DEPENDS:=+trusted-firmware-a-mt7986-spim-nand-4k-ddr4 endef +define U-Boot/mt7988_arcadyan_mozart + NAME:=Arcadyan Mozart + BUILD_SUBTARGET:=filogic + BUILD_DEVICES:=arcadyan_mozart + UBOOT_CONFIG:=mt7988a_arcadyan_mozart + UBOOT_IMAGE:=u-boot.fip + BL2_BOOTDEV:=emmc + BL2_SOC:=mt7988 + BL2_DDRTYPE:=comb + DEPENDS:=+trusted-firmware-a-mt7988-emmc-comb +endef + define U-Boot/mt7988_bananapi_bpi-r4-emmc NAME:=BananaPi BPi-R4 BUILD_SUBTARGET:=filogic @@ -816,6 +828,7 @@ UBOOT_TARGETS := \ mt7986_xiaomi_redmi-router-ax6000 \ mt7986_zyxel_ex5601-t0 \ mt7986_rfb \ + mt7988_arcadyan_mozart \ mt7988_bananapi_bpi-r4-emmc \ mt7988_bananapi_bpi-r4-sdmmc \ mt7988_bananapi_bpi-r4-snand \ diff --git a/package/boot/uboot-mediatek/patches/456-add-arcadyan-mozart.patch b/package/boot/uboot-mediatek/patches/456-add-arcadyan-mozart.patch new file mode 100644 index 00000000000..5c9c6e69771 --- /dev/null +++ b/package/boot/uboot-mediatek/patches/456-add-arcadyan-mozart.patch @@ -0,0 +1,308 @@ +--- /dev/null ++++ b/configs/mt7988a_arcadyan_mozart_defconfig +@@ -0,0 +1,119 @@ ++CONFIG_ARM=y ++CONFIG_SYS_HAS_NONCACHED_MEMORY=y ++CONFIG_POSITION_INDEPENDENT=y ++CONFIG_ARCH_MEDIATEK=y ++CONFIG_TEXT_BASE=0x41e00000 ++CONFIG_SYS_MALLOC_F_LEN=0x4000 ++CONFIG_NR_DRAM_BANKS=1 ++CONFIG_ENV_SIZE=0x40000 ++CONFIG_ENV_OFFSET=0x400000 ++CONFIG_DEFAULT_DEVICE_TREE="mt7988a-arcadyan-mozart" ++CONFIG_OF_LIBFDT_OVERLAY=y ++CONFIG_TARGET_MT7988=y ++CONFIG_PRE_CON_BUF_ADDR=0x4007EF00 ++CONFIG_DEBUG_UART_BASE=0x11000000 ++CONFIG_DEBUG_UART_CLOCK=40000000 ++CONFIG_ENV_OFFSET_REDUND=0x440000 ++CONFIG_SYS_LOAD_ADDR=0x50000000 ++CONFIG_PCI=y ++CONFIG_DEBUG_UART=y ++CONFIG_AHCI=y ++CONFIG_FIT=y ++CONFIG_BOOTDELAY=30 ++CONFIG_AUTOBOOT_KEYED=y ++CONFIG_AUTOBOOT_MENU_SHOW=y ++CONFIG_OF_SYSTEM_SETUP=y ++CONFIG_DEFAULT_FDT_FILE="mediatek/mt7988a-arcadyan-mozart.dtb" ++CONFIG_SYS_CBSIZE=512 ++CONFIG_SYS_PBSIZE=1049 ++CONFIG_LOGLEVEL=7 ++CONFIG_PRE_CONSOLE_BUFFER=y ++CONFIG_LOG=y ++CONFIG_BOARD_LATE_INIT=y ++CONFIG_HUSH_PARSER=y ++CONFIG_SYS_PROMPT="MT7988> " ++CONFIG_CMD_CPU=y ++CONFIG_CMD_LICENSE=y ++# CONFIG_CMD_BOOTEFI_BOOTMGR is not set ++CONFIG_CMD_BOOTMENU=y ++CONFIG_CMD_ASKENV=y ++CONFIG_CMD_ERASEENV=y ++CONFIG_CMD_ENV_FLAGS=y ++CONFIG_CMD_STRINGS=y ++CONFIG_CMD_DM=y ++CONFIG_CMD_GPIO=y ++CONFIG_CMD_PWM=y ++CONFIG_CMD_GPT=y ++CONFIG_CMD_MMC=y ++CONFIG_CMD_MTD=y ++CONFIG_CMD_PART=y ++CONFIG_CMD_PCI=y ++CONFIG_CMD_SF_TEST=y ++CONFIG_CMD_USB=y ++CONFIG_CMD_DHCP=y ++CONFIG_CMD_TFTPSRV=y ++CONFIG_CMD_RARP=y ++CONFIG_CMD_PING=y ++CONFIG_CMD_CDP=y ++CONFIG_CMD_SNTP=y ++CONFIG_CMD_DNS=y ++CONFIG_CMD_LINK_LOCAL=y ++CONFIG_CMD_PXE=y ++CONFIG_CMD_CACHE=y ++CONFIG_CMD_PSTORE=y ++CONFIG_CMD_PSTORE_MEM_ADDR=0x42ff0000 ++CONFIG_CMD_UUID=y ++CONFIG_CMD_HASH=y ++CONFIG_CMD_SMC=y ++CONFIG_CMD_EXT4=y ++CONFIG_CMD_FAT=y ++CONFIG_CMD_FS_GENERIC=y ++CONFIG_CMD_FS_UUID=y ++CONFIG_OF_EMBED=y ++CONFIG_ENV_OVERWRITE=y ++CONFIG_ENV_IS_IN_MMC=y ++CONFIG_SYS_REDUNDAND_ENVIRONMENT=y ++CONFIG_SYS_RELOC_GD_ENV_ADDR=y ++CONFIG_USE_DEFAULT_ENV_FILE=y ++CONFIG_DEFAULT_ENV_FILE="arcadyan_mozart_env" ++CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y ++CONFIG_VERSION_VARIABLE=y ++CONFIG_NET_RANDOM_ETHADDR=y ++CONFIG_NETCONSOLE=y ++CONFIG_USE_IPADDR=y ++CONFIG_IPADDR="192.168.1.1" ++CONFIG_USE_SERVERIP=y ++CONFIG_SERVERIP="192.168.1.254" ++CONFIG_REGMAP=y ++CONFIG_SYSCON=y ++CONFIG_BUTTON=y ++CONFIG_BUTTON_GPIO=y ++CONFIG_CLK=y ++CONFIG_GPIO_HOG=y ++CONFIG_LED=y ++CONFIG_LED_BLINK=y ++CONFIG_LED_GPIO=y ++CONFIG_SUPPORT_EMMC_BOOT=y ++CONFIG_MMC_HS200_SUPPORT=y ++CONFIG_MMC_MTK=y ++CONFIG_PHY_FIXED=y ++CONFIG_MEDIATEK_ETH=y ++CONFIG_PHY=y ++CONFIG_PHY_MTK_TPHY=y ++CONFIG_PINCTRL=y ++CONFIG_PINCONF=y ++CONFIG_PINCTRL_MT7988=y ++CONFIG_POWER_DOMAIN=y ++CONFIG_MTK_POWER_DOMAIN=y ++CONFIG_DM_REGULATOR=y ++CONFIG_DM_REGULATOR_FIXED=y ++CONFIG_DM_REGULATOR_GPIO=y ++CONFIG_DM_PWM=y ++CONFIG_PWM_MTK=y ++CONFIG_RAM=y ++CONFIG_SCSI=y ++CONFIG_DM_SERIAL=y ++CONFIG_MTK_SERIAL=y ++CONFIG_ZSTD=y ++CONFIG_HEXDUMP=y ++CONFIG_LMB_MAX_REGIONS=64 +--- /dev/null ++++ b/arcadyan_mozart_env +@@ -0,0 +1,55 @@ ++ipaddr=192.168.1.1 ++serverip=192.168.1.254 ++loadaddr=0x50000000 ++bootargs=console=ttyS0,115200n1 pci=pcie_bus_perf root=/dev/fit0 rootwait ++bootcmd=if pstore check ; then run boot_recovery ; else run boot_emmc ; fi ++bootconf=config-1 ++bootconf_extra= ++bootdelay=0 ++bootfile=openwrt-mediatek-filogic-arcadyan_mozart-initramfs.itb ++bootfile_bl2=openwrt-mediatek-filogic-arcadyan_mozart-emmc-preloader.bin ++bootfile_fip=openwrt-mediatek-filogic-arcadyan_mozart-emmc-bl31-uboot.fip ++bootfile_upg=openwrt-mediatek-filogic-arcadyan_mozart-squashfs-sysupgrade.itb ++bootled_pwr=blue:status ++bootled_rec=red:status ++bootmenu_confirm_return=askenv - Press ENTER to return to menu ; bootmenu 60 ++bootmenu_default=0 ++bootmenu_delay=0 ++bootmenu_title= ( ( ( OpenWrt ) ) ) [eMMC] ++bootmenu_0=Initialize environment.=run _firstboot ++bootmenu_0d=Run default boot command.=run boot_default ++bootmenu_1=Boot system via TFTP.=run boot_tftp ; run bootmenu_confirm_return ++bootmenu_2=Boot production system from eMMC.=run boot_production ; run bootmenu_confirm_return ++bootmenu_3=Boot recovery system from eMMC.=run boot_recovery ; run bootmenu_confirm_return ++bootmenu_4=Load production system via TFTP then write to eMMC.=setenv noboot 1 ; setenv replacevol 1 ; run boot_tftp_production ; setenv noboot ; setenv replacevol ; run bootmenu_confirm_return ++bootmenu_5=Load recovery system via TFTP then write to eMMC.=setenv noboot 1 ; setenv replacevol 1 ; run boot_tftp_recovery ; setenv noboot ; setenv replacevol ; run bootmenu_confirm_return ++bootmenu_6=Load BL31+U-Boot FIP via TFTP then write to eMMC.=run boot_tftp_write_fip ; run bootmenu_confirm_return ++bootmenu_7=Load BL2 preloader via TFTP then write to eMMC.=run boot_tftp_write_bl2 ; run bootmenu_confirm_return ++bootmenu_8=Reboot.=reset ++bootmenu_9=Reset all settings to factory defaults.=run reset_factory ; reset ++boot_first=if button reset ; then led $bootled_rec on ; run boot_tftp_recovery ; setenv flag_recover 1 ; run boot_default ; fi ; bootmenu ++boot_default=if env exists flag_recover ; then else run bootcmd ; fi ; run boot_recovery ; setenv replacevol 1 ; run boot_tftp_forever ++boot_production=led $bootled_pwr on ; run emmc_read_production && bootm $loadaddr#$bootconf#$bootconf_extra ; led $bootled_pwr off ++boot_recovery=led $bootled_rec on ; run emmc_read_recovery && bootm $loadaddr#$bootconf#$bootconf_extra ; led $bootled_rec off ++boot_emmc=run boot_production ; run boot_recovery ++boot_tftp_forever=led $bootled_rec on ; while true ; do run boot_tftp_recovery ; sleep 1 ; done ++boot_tftp_production=tftpboot $loadaddr $bootfile_upg && env exists replacevol && iminfo $loadaddr && run emmc_write_production ; if env exists noboot ; then else bootm $loadaddr#$bootconf#$bootconf_extra ; fi ++boot_tftp_recovery=tftpboot $loadaddr $bootfile && env exists replacevol && iminfo $loadaddr && run emmc_write_recovery ; if env exists noboot ; then else bootm $loadaddr#$bootconf ; fi ++boot_tftp_write_fip=tftpboot $loadaddr $bootfile_fip && run emmc_write_fip ++boot_tftp_write_bl2=tftpboot $loadaddr $bootfile_bl2 && run emmc_write_bl2 ++boot_tftp=tftpboot $loadaddr $bootfile && bootm $loadaddr#$bootconf ++mmc_write_vol=imszb $loadaddr image_size && test 0x$image_size -le 0x$part_size && mmc erase 0x$part_addr 0x$image_size && mmc write $loadaddr 0x$part_addr 0x$image_size ++mmc_read_vol=mmc read $loadaddr $part_addr 0x100 && imszb $loadaddr image_size && test 0x$image_size -le 0x$part_size && mmc read $loadaddr 0x$part_addr 0x$image_size && setexpr filesize $image_size * 0x200 ++part_default=production ++part_recovery=recovery ++reset_factory=eraseenv && reset ++emmc_read_production=part start mmc 0 $part_default part_addr && part size mmc 0 $part_default part_size && run mmc_read_vol ++emmc_read_recovery=part start mmc 0 $part_recovery part_addr && part size mmc 0 $part_recovery part_size && run mmc_read_vol ++emmc_write_bl2=mmc partconf 0 1 1 1 && mmc erase 0x0 0x400 && mmc write $fileaddr 0x0 0x400 ; mmc partconf 0 1 1 0 ++emmc_write_fip=mmc erase 0x3400 0x2000 && mmc write $fileaddr 0x3400 0x2000 && mmc erase 0x2000 0x800 ++emmc_write_production=part start mmc 0 $part_default part_addr && part size mmc 0 $part_default part_size && run mmc_write_vol ++emmc_write_recovery=part start mmc 0 $part_recovery part_addr && part size mmc 0 $part_recovery part_size && run mmc_write_vol ++_init_env=setenv _init_env ; setenv _create_env ; saveenv ; saveenv ++_firstboot=setenv _firstboot ; run _switch_to_menu ; run _init_env ; run boot_first ++_switch_to_menu=setenv _switch_to_menu ; setenv bootdelay 3 ; setenv bootmenu_delay 3 ; setenv bootmenu_0 $bootmenu_0d ; setenv bootmenu_0d ; run _bootmenu_update_title ++_bootmenu_update_title=setenv _bootmenu_update_title ; setenv bootmenu_title "$bootmenu_title $ver" +--- /dev/null ++++ b/arch/arm/dts/mt7988a-arcadyan-mozart.dts +@@ -0,0 +1,125 @@ ++// SPDX-License-Identifier: GPL-2.0 ++ ++/dts-v1/; ++#include "mt7988.dtsi" ++#include ++#include ++ ++/ { ++ model = "MediaTek / Arcadyan - Mozart"; ++ compatible = "arcadyan,mozart", "mediatek,mt7988"; ++ ++ chosen { ++ stdout-path = &uart0; ++ }; ++ ++ memory@40000000 { ++ device_type = "memory"; ++ reg = <0 0x40000000 0 0x40000000>; ++ }; ++ ++ reg_3p3v: regulator-3p3v { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-3.3V"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ reg_1p8v: regulator-1p8v { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-1.8V"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ keys { ++ compatible = "gpio-keys"; ++ ++ wps { ++ label = "reset"; ++ linux,code = ; ++ gpios = <&gpio 143 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ led-red { ++ label = "red:status"; ++ gpios = <&gpio 29 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ led-green { ++ label = "blue:status"; ++ gpios = <&gpio 30 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ led-blue { ++ label = "blue:status"; ++ gpios = <&gpio 31 GPIO_ACTIVE_HIGH>; ++ }; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++ð { ++ status = "okay"; ++ mediatek,gmac-id = <0>; ++ phy-mode = "usxgmii"; ++ mediatek,switch = "mt7988"; ++ ++ fixed-link { ++ speed = <1000>; ++ full-duplex; ++ pause; ++ }; ++}; ++ ++&pinctrl { ++ mmc0_pins_default: mmc0default { ++ mux { ++ function = "flash"; ++ groups = "emmc_51"; ++ }; ++ ++ conf-cmd-dat { ++ pins = "EMMC_DATA_0", "EMMC_DATA_1", "EMMC_DATA_2", ++ "EMMC_DATA_3", "EMMC_DATA_4", "EMMC_DATA_5", ++ "EMMC_DATA_6", "EMMC_DATA_7", "EMMC_CMD"; ++ input-enable; ++ }; ++ ++ conf-clk { ++ pins = "EMMC_CK"; ++ }; ++ ++ conf-dsl { ++ pins = "EMMC_DSL"; ++ }; ++ ++ conf-rst { ++ pins = "EMMC_RSTB"; ++ }; ++ }; ++}; ++ ++&mmc0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mmc0_pins_default>; ++ max-frequency = <52000000>; ++ bus-width = <8>; ++ cap-mmc-highspeed; ++ cap-mmc-hw-reset; ++ vmmc-supply = <®_3p3v>; ++ vqmmc-supply = <®_1p8v>; ++ non-removable; ++ status = "okay"; ++}; From cfe8e6e75fed4d18f234334b96061fbbb7fd0c64 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Tue, 29 Oct 2024 13:37:40 +0100 Subject: [PATCH 23/27] mediatek: add support for Realtek RTL8261n 10G PHYs There is no upstream driver yet. Merge the RTL SDK driver for now. Signed-off-by: John Crispin --- .../drivers/net/phy/rtl8261n/Kconfig | 5 + .../drivers/net/phy/rtl8261n/Makefile | 11 + .../phy/rtl8261n/construct/conf_rtl8261n_c.c | 1465 +++++++++++ .../phy/rtl8261n/construct/conf_rtl8264b.c | 2177 +++++++++++++++++ .../drivers/net/phy/rtl8261n/error.h | 165 ++ .../drivers/net/phy/rtl8261n/phy_patch.c | 179 ++ .../drivers/net/phy/rtl8261n/phy_patch.h | 174 ++ .../net/phy/rtl8261n/phy_rtl826xb_patch.c | 1031 ++++++++ .../net/phy/rtl8261n/phy_rtl826xb_patch.h | 63 + .../drivers/net/phy/rtl8261n/rtk_osal.c | 56 + .../drivers/net/phy/rtl8261n/rtk_osal.h | 99 + .../drivers/net/phy/rtl8261n/rtk_phy.c | 282 +++ .../drivers/net/phy/rtl8261n/rtk_phylib.c | 108 + .../drivers/net/phy/rtl8261n/rtk_phylib.h | 101 + .../drivers/net/phy/rtl8261n/rtk_phylib_def.h | 166 ++ .../net/phy/rtl8261n/rtk_phylib_rtl826xb.c | 57 + .../net/phy/rtl8261n/rtk_phylib_rtl826xb.h | 19 + .../files-6.6/drivers/net/phy/rtl8261n/type.h | 117 + target/linux/mediatek/filogic/config-6.6 | 1 + target/linux/mediatek/mt7622/config-6.6 | 1 + target/linux/mediatek/mt7623/config-6.6 | 1 + target/linux/mediatek/mt7629/config-6.6 | 1 + .../735-net-phy-realtek-rtl8261n.patch | 21 + 23 files changed, 6300 insertions(+) create mode 100644 target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/Kconfig create mode 100644 target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/Makefile create mode 100644 target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/construct/conf_rtl8261n_c.c create mode 100644 target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/construct/conf_rtl8264b.c create mode 100644 target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/error.h create mode 100644 target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/phy_patch.c create mode 100644 target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/phy_patch.h create mode 100644 target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/phy_rtl826xb_patch.c create mode 100644 target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/phy_rtl826xb_patch.h create mode 100644 target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/rtk_osal.c create mode 100644 target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/rtk_osal.h create mode 100644 target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/rtk_phy.c create mode 100644 target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/rtk_phylib.c create mode 100644 target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/rtk_phylib.h create mode 100644 target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/rtk_phylib_def.h create mode 100644 target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/rtk_phylib_rtl826xb.c create mode 100644 target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/rtk_phylib_rtl826xb.h create mode 100644 target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/type.h create mode 100644 target/linux/mediatek/patches-6.6/735-net-phy-realtek-rtl8261n.patch diff --git a/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/Kconfig b/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/Kconfig new file mode 100644 index 00000000000..cdb5cb74882 --- /dev/null +++ b/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/Kconfig @@ -0,0 +1,5 @@ + +config RTL8261N_PHY + tristate "Driver for Realtek RTL8261N PHYs" + help + Currently supports the RTL8261N,RTL8264B PHYs. diff --git a/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/Makefile b/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/Makefile new file mode 100644 index 00000000000..a661d6ce85e --- /dev/null +++ b/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/Makefile @@ -0,0 +1,11 @@ + +obj-$(CONFIG_RTL8261N_PHY) += rtl8621n.o + +rtl8621n-objs += phy_patch.o +rtl8621n-objs += phy_rtl826xb_patch.o +rtl8621n-objs += rtk_osal.o +rtl8621n-objs += rtk_phy.o +rtl8621n-objs += rtk_phylib.o +rtl8621n-objs += rtk_phylib_rtl826xb.o + +ccflags-y += -Werror -DRTK_PHYDRV_IN_LINUX diff --git a/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/construct/conf_rtl8261n_c.c b/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/construct/conf_rtl8261n_c.c new file mode 100644 index 00000000000..8e7c714fc40 --- /dev/null +++ b/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/construct/conf_rtl8261n_c.c @@ -0,0 +1,1465 @@ +/* + * SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved. + */ + +//Date: Tue Nov 15 19:53:03 2022 + +rtk_hwpatch_t rtl8261n_c_top_conf[] = { + {RTK_PATCH_OP_TOP , 0xf , 2 , 20 , 15, 0 , 0x5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 2 , 21 , 15, 0 , 0x0 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 2 , 22 , 15, 0 , 0x280 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 2 , 23 , 15, 0 , 0x0014, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 3 , 16 , 15, 0 , 0x0300, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 3 , 17 , 15, 0 , 0x01ff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 3 , 18 , 15, 0 , 0x000c, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 3 , 19 , 15, 0 , 0x01ff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 3 , 20 , 15, 0 , 0x0200, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 3 , 21 , 15, 0 , 0x0015, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 3 , 22 , 15, 0 , 0x0200, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 3 , 23 , 15, 0 , 0x0 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 4 , 16 , 15, 0 , 0x0 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 13 , 23 , 8 , 5 , 0x6 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 90 , 18 , 15, 0 , 0x5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 90 , 19 , 15, 0 , 0x5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 90 , 20 , 15, 8 , 0x01 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, +}; + +rtk_hwpatch_t rtl8261n_c_sds_conf[] = { + {RTK_PATCH_OP_TOP , 0xf , 24 , 18 , 15, 0 , 0x881F, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 24 , 19 , 15, 0 , 0x003F, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 24 , 20 , 15, 0 , 0x003F, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 24 , 21 , 15, 0 , 0x003F, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 24 , 22 , 15, 0 , 0x001F, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x06 , 0x0D , 15, 0 , 0x0F00, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x06 , 0x0E , 15, 0 , 0x3F5A, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x07 , 0x10 , 15, 12, 0x8 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x07 , 0x10 , 7 , 0 , 0x3 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x06 , 0x1D , 15, 0 , 0x0600, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x21 , 0x00 , 15, 0 , 0x4902, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x21 , 0x08 , 15, 0 , 0x0FC0, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x21 , 0x09 , 15, 0 , 0x33F0, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x21 , 0x0C , 15, 0 , 0x08BF, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x21 , 0x12 , 15, 0 , 0x8000, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x36 , 0x07 , 15, 0 , 0x04C0, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x36 , 0x08 , 15, 0 , 0x2000, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2E , 0x0B , 15, 0 , 0x2390, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2E , 0x0C , 15, 0 , 0xAA17, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2E , 0x0D , 15, 0 , 0xFE40, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2E , 0x0E , 15, 0 , 0x12F4, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2E , 0x11 , 15, 0 , 0xF2AD, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2E , 0x15 , 15, 0 , 0x7A41, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2E , 0x16 , 15, 0 , 0x0041, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2F , 0x00 , 15, 0 , 0x1F00, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2F , 0x01 , 15, 0 , 0x2800, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2F , 0x02 , 15, 0 , 0x0FC8, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2F , 0x11 , 15, 0 , 0x3000, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2F , 0x13 , 15, 0 , 0xF400, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2F , 0x1E , 15, 0 , 0x0500, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x34 , 0x0B , 15, 0 , 0x2390, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x34 , 0x0C , 15, 0 , 0xA517, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x34 , 0x0D , 15, 0 , 0xFE41, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x34 , 0x0E , 15, 0 , 0x12F4, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x34 , 0x11 , 15, 0 , 0xF2AD, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x34 , 0x15 , 15, 0 , 0x7A41, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x34 , 0x16 , 15, 0 , 0x0041, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x35 , 0x00 , 15, 0 , 0x1F80, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x35 , 0x01 , 15, 0 , 0x0800, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x35 , 0x02 , 15, 0 , 0x0FC8, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x35 , 0x11 , 15, 0 , 0x3001, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x35 , 0x13 , 15, 0 , 0xF400, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x35 , 0x1E , 15, 0 , 0x0100, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2C , 0x0B , 15, 0 , 0x2390, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2C , 0x0C , 15, 0 , 0xA517, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2C , 0x0D , 15, 0 , 0xFE41, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2C , 0x0E , 15, 0 , 0x12F4, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2C , 0x11 , 15, 0 , 0xF2AD, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2C , 0x15 , 15, 0 , 0x7A61, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2C , 0x16 , 15, 0 , 0x0041, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2D , 0x00 , 15, 0 , 0x1F80, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2D , 0x01 , 15, 0 , 0x0800, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2D , 0x02 , 15, 0 , 0x0FC8, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2D , 0x11 , 15, 0 , 0x3001, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2D , 0x13 , 15, 0 , 0xF400, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2D , 0x1E , 15, 0 , 0x0100, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x28 , 0x0B , 15, 0 , 0x2390, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x28 , 0x0C , 15, 0 , 0xA514, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x28 , 0x0D , 15, 0 , 0xFE43, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x28 , 0x0E , 15, 0 , 0x12F4, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x28 , 0x11 , 15, 0 , 0xF2AD, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x28 , 0x15 , 15, 0 , 0x7A61, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x28 , 0x16 , 15, 0 , 0x0041, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x29 , 0x00 , 15, 0 , 0x1F80, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x29 , 0x01 , 15, 0 , 0x0800, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x29 , 0x02 , 15, 0 , 0x0FC8, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x29 , 0x11 , 15, 0 , 0x3001, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x29 , 0x13 , 15, 0 , 0xF400, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x29 , 0x1E , 15, 0 , 0x0100, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x26 , 0x0B , 15, 0 , 0x2390, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x26 , 0x0C , 15, 0 , 0xA514, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x26 , 0x0D , 15, 0 , 0xFE43, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x26 , 0x0E , 15, 0 , 0x12F4, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x26 , 0x11 , 15, 0 , 0xF2AD, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x26 , 0x15 , 15, 0 , 0x7A41, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x26 , 0x16 , 15, 0 , 0x0041, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x27 , 0x00 , 15, 0 , 0x1F80, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x27 , 0x01 , 15, 0 , 0x0800, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x27 , 0x02 , 15, 0 , 0x0FC8, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x27 , 0x11 , 15, 0 , 0x3001, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x27 , 0x13 , 15, 0 , 0xF400, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x27 , 0x1E , 15, 0 , 0x0100, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x24 , 0x0B , 15, 0 , 0x2390, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x24 , 0x0C , 15, 0 , 0xA514, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x24 , 0x0D , 15, 0 , 0xFE43, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x24 , 0x0E , 15, 0 , 0x12F4, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x24 , 0x11 , 15, 0 , 0xF2AD, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x24 , 0x15 , 15, 0 , 0x7A41, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x24 , 0x16 , 15, 0 , 0x0041, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x25 , 0x00 , 15, 0 , 0x1F80, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x25 , 0x01 , 15, 0 , 0x0800, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x25 , 0x02 , 15, 0 , 0x0FC8, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x25 , 0x11 , 15, 0 , 0x3001, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x25 , 0x13 , 15, 0 , 0xF400, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x25 , 0x1E , 15, 0 , 0x0100, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 24 , 18 , 15, 0 , 0x880D, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 24 , 19 , 15, 0 , 0x0024, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 24 , 20 , 15, 0 , 0x0036, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 24 , 21 , 15, 0 , 0x0035, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 24 , 22 , 15, 0 , 0x001A, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x1F , 0x00 , 15, 0 , 0x001B, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x1F , 0x00 , 15, 0 , 0x0000, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 90 , 20 , 7 , 0 , 0x01 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, +}; + +rtk_hwpatch_t rtl8261n_c_afe_conf[] = { +}; + +rtk_hwpatch_t rtl8261n_c_uc_conf[] = { + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb820, 7 , 7 , 0x0 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbd8a, 5 , 3 , 0x3 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbd8c, 6 , 4 , 0x5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x8060, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 12, 10, 0x3 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x8061, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 13, 0x5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa466, 1 , 1 , 0x1 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x8491, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x3D , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, +}; + +rtk_hwpatch_t rtl8261n_c_uc2_conf[] = { + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb820, 7 , 7 , 0x1 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb87c, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8af6, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb87e, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf8b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8af6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0eaf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8af8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8b41, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8afa}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf8b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8afc}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4faf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8afe}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8b5b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b00}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf8b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b02}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xb4af, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b04}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8bc0, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b06}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf8b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b08}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xdaaf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b0a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8bda, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b0c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf8ef, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b0e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x49f8, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b10}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf70, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b12}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3f02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b14}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6772, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b16}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xad28, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b18}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13e1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b1a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8a55, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b1c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xad28, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b1e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0502, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b20}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5ee2, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b22}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xae0e, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b24}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x025d, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b26}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8f02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b28}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8bda, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b2a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xae06, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b2c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x025d, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b2e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7002, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b30}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8c22, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b32}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe087, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b34}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1ef6, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b36}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x27e4, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b38}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x871e, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b3a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfcef, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b3c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x94fc, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b3e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x04a1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b40}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0103, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b42}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x028b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b44}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfee0, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b46}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8a09, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b48}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xef23, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b4a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf5e, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b4c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5bac, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b4e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5003, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b50}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf62, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b52}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8a02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b54}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8c22, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b56}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf62, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b58}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xb0bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b5a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x68e0, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b5c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0267, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b5e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x72ef, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b60}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x31bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b62}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x68dd, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b64}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0267, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b66}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x721e, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b68}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x31ac, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b6a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3819, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b6c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf68, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b6e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe902, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b70}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6772, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b72}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xef31, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b74}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf68, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b76}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe602, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b78}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6772, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b7a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1e31, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b7c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xac38, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b7e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cee, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b80}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8933, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b82}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x02ae, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b84}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0aee, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b86}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8933, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b88}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x00ae, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b8a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x04ee, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b8c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8933, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b8e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x01bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b90}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8ff9, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b92}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe189, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b94}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x331a, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b96}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x91db, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b98}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf69, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b9a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4c02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b9c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6772, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b9e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1f00, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ba0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1f22, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ba2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1b45, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ba4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xad27, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ba6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x05e1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ba8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x870d, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8baa}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xae03, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bac}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe187, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bae}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0eaf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bb0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2d1a, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bb2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0248, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bb4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf702, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bb6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8c46, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bb8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0222, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bba}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4faf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bbc}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4176, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bbe}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf8c, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bc0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9002, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bc2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70eb, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bc4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf8c, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bc6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9f02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bc8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70eb, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bca}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf8c, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bcc}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa502, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bce}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70eb, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bd0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd300, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bd2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0241, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bd4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7caf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bd6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x46b2, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bd8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf8ef, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bda}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x49f8, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bdc}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bde}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3a02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8be0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6772, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8be2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xac28, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8be4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x12bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8be6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6d63, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8be8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0267, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bea}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x72e5, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bec}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8ffc, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bee}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6d, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bf0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6f02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bf2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6772, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bf4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe58f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bf6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfdfc, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bf8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xef94, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bfa}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfc04, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bfc}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf8ef, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bfe}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x49f8, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c00}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c02}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3a02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c04}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6772, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c06}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xac28, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c08}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x12e1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c0a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8ffe, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c0c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6d, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c0e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6302, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c10}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6753, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c12}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe18f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c14}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffbf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c16}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6d6f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c18}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0267, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c1a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x53fc, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c1c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xef94, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c1e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfc04, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c20}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf8ef, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c22}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x49f8, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c24}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c26}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3a02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c28}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6772, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c2a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xac28, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c2c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x12e1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c2e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8ffc, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c30}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6d, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c32}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6302, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c34}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6753, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c36}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe18f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c38}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfdbf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c3a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6d6f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c3c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0267, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c3e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x53fc, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c40}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xef94, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c42}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfc04, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c44}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf8fa, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c46}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xef69, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c48}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c4a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3a02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c4c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6772, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c4e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xad28, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c50}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0ebf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c52}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8c93, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c54}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c56}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf4bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c58}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8c90, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c5a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c5c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf4ae, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c5e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2ad1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c60}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0fbf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c62}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8c96, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c64}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0267, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c66}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x53bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c68}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8c99, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c6a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c6c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xebd1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c6e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x00bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c70}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8c9c, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c72}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0267, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c74}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x53bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c76}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8c9f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c78}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c7a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf4d1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c7c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x00bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c7e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8ca2, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c80}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0267, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c82}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x53bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c84}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8ca5, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c86}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c88}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf4ef, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c8a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x96fe, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c8c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfc04, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c8e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x77bd, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c90}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6c66, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c92}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbd6c, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c94}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x30bd, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c96}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5444, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c98}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbd54, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c9a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x85bd, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c9c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5e55, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c9e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbd54, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ca0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa7bd, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ca2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5cbb, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ca4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbd5c, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ca6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb85e, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x62ba, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb860, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5e56, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb862, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6287, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb864, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2d07, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb886, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4170, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb888, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x46ad, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb88a, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb88c, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb838, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x003f, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb820, 7 , 7 , 0x0 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, +}; + +rtk_hwpatch_t rtl8261n_c_nctl0_conf[] = { + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb820, 7 , 7 , 0x1 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA016, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA012, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA014, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8010, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x801a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x801a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x801a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x801a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x801a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x801a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x801a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd719, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x10}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3bb7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x11}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8014, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x12}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x13}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd704, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x14}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x406e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x15}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x16}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x12db, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x17}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x18}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1301, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x19}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA026, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA024, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA022, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA020, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA006, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA004, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA002, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA000, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x12d7, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA008, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0100, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb820, 7 , 7 , 0x0 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, +}; + +rtk_hwpatch_t rtl8261n_c_nctl1_conf[] = { +}; + +rtk_hwpatch_t rtl8261n_c_nctl2_conf[] = { + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb820, 7 , 7 , 0x1 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA016, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0020, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA012, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA014, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8010, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8029, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8217, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x82d0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x82f9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8322, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8322, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8322, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x10}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x11}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcb0a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x12}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cc7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x13}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x14}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x15}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x16}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4127, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x17}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x18}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x19}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c0f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b05, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c38, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0d28, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf008, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x20}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x21}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c0f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x22}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b0a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x23}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c38, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x24}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0d18, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x25}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x26}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x27}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0f73, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x28}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x29}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8034, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8031, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1bf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd06d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x30}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1dd, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x31}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd06d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x32}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x33}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd199, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x34}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd06e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x35}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x36}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x37}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x38}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5fba, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x39}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd05a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x60cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x60f1, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6113, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6135, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x40}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6157, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x41}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x42}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x43}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x44}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x45}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf008, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x46}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x47}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x48}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x49}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf004, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf002, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x142d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x50}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x51}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0ccf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x52}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b40, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x53}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c3f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x54}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c24, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x55}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x56}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa340, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x57}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x58}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x147c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x59}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa110, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1435, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8110, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1485, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa304, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x60}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa8c0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x61}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8810, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x62}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x63}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa120, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x64}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa310, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x65}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cfc, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x66}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0224, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x67}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0ca0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x68}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0480, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x69}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa340, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd162, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x70}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x71}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x72}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5fba, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x73}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8840, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x74}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1c4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x75}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd045, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x76}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x77}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x78}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x79}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5fba, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x7a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x7b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6127, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x7c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x7d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f3b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x7e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x88c0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x7f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x800a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x80}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8120, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x81}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8350, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x82}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x84a0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x83}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffb6, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x84}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xb920, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x85}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcd33, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x86}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x87}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x88}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x89}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7fb4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x8a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9920, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x8b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x8c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x8d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x8e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6065, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x8f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f94, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x90}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffee, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x91}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xb820, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x92}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x93}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x94}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x95}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7fa5, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x96}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9820, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x97}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x800a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x98}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8120, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x99}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x9a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x147c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x9b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa108, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x9c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x9d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1435, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x9e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8108, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x9f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1485, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa2fc, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa304, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8880, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cc0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0440, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcd34, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cc0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xaa}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b80, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xab}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xac3f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xac}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c38, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xad}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0d08, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xae}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xaf}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa810, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa120, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa480, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa604, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x80bb, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd049, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xba}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd19f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xbb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd049, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xbc}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xbd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xbe}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xbf}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x63f4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f7a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4368, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cc0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b40, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8c3f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8d38, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xca}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xcb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xcc}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xcd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x80d7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xce}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xcf}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x80d4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1f4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1b7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1c6, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xda}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xdb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6074, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xdc}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xdd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f7a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xde}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xdf}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4056, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf004, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x61fc, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfff9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xea}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4070, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xeb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xec}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x81a4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xed}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xee}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xef}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xae80, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x81a4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd05a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x60cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x60f1, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6113, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6135, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xfa}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6157, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xfb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xfc}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xfd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xfe}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xff}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf008, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x100}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x101}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x102}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x103}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf004, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x104}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x105}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf002, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x106}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x107}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x108}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x142d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x109}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x10a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x10b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0ccf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x10c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b40, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x10d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c3f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x10e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c24, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x10f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x110}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa340, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x111}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x112}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x147c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x113}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa110, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x114}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x115}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1435, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x116}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8110, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x117}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x118}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1485, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x119}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa304, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x11a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa8c0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x11b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8810, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x11c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x11d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa120, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x11e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa310, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x11f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cfc, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x120}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0224, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x121}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0ca0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x122}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0480, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x123}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8604, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x124}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcd35, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x125}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd162, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x126}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x127}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x128}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x129}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x12a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5fba, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x12b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8840, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x12c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1c4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x12d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd045, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x12e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x12f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x130}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x131}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5fba, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x132}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x133}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6127, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x134}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x135}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f3b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x136}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x88c0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x137}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x800a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x138}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8120, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x139}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8350, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x13a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x84a0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x13b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffb8, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x13c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbb80, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x13d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x13e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x13f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x140}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5fb4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x141}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xb920, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x142}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcd36, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x143}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x144}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x145}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x146}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7fb4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x147}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9920, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x148}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9b80, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x149}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x14a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x14b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x14c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6065, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x14d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f94, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x14e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffe8, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x14f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xb820, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x150}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x151}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x152}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x153}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7fa5, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x154}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9820, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x155}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x800a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x156}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8120, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x157}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x158}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x147c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x159}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa108, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x15a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x15b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1435, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x15c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8108, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x15d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x15e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1485, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x15f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa2fc, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x160}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa304, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x161}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8880, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x162}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cc0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x163}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0440, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x164}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcd37, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x165}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x166}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x167}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cc0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x168}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b80, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x169}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xac3f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x16a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c38, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x16b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0d08, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x16c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x16d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa810, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x16e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x16f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa120, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x170}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa480, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x171}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa604, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x172}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x173}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x174}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x817e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x175}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x176}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x817b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x177}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x178}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x179}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x17a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x17b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x17c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x17d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x17e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x17f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x180}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x181}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x182}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1463, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x183}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x184}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f7a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x185}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x186}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f28, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x187}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x188}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x189}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cc0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x18a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b40, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x18b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8c3f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x18c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8d38, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x18d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x18e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x18f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x190}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x819a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x191}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x192}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8197, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x193}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd199, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x194}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x195}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x196}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x197}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x198}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x199}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd189, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x19a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x19b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x19c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x19d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x19e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1463, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x19f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f7a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f28, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c0f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b05, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x60cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1aa}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x60f1, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ab}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6113, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ac}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6135, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ad}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6157, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ae}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1af}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce08, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce08, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf008, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce08, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce08, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf004, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce08, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf002, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce08, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ba}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1bb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x142d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1bc}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa180, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1bd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcd38, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1be}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1bf}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x81d4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x81cc, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf013, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd100, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd049, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ca}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf010, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1cb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1cc}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1cd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1b7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ce}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd049, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1cf}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd100, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf008, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd199, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1da}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd13b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1db}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd055, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1dc}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1dd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1de}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1df}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1463, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f7b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa302, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1463, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f7a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ea}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f28, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1eb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ec}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ed}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c3f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ee}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c12, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ef}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8206, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x81fe, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd199, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf013, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1fa}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd100, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1fb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1fc}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf010, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1fd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1fe}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ff}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x200}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x201}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x202}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd100, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x203}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd040, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x204}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf008, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x205}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x206}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x207}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd199, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x208}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x209}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x20a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd16b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x20b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x20c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x20d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x20e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x20f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1463, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x210}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x211}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f7a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x212}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x213}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f2a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x214}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x215}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x087a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x216}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x217}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x646d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x218}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x219}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8231, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x21a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x21b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8227, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x21c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x21d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x40c7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x21e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x21f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x220}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd100, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x221}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd049, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x222}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf01a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x223}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x224}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd049, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x225}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf017, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x226}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x227}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x40c7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x228}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x229}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x22a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd100, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x22b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd049, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x22c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf010, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x22d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x22e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x22f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x230}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x231}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x40c7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x232}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x233}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x234}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x235}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x236}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x237}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x238}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x239}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x23a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x23b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x23c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x23d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x23e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x23f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1463, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x240}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x241}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f7a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x242}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x243}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f29, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x244}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x245}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x60cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x246}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x60f1, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x247}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6113, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x248}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6135, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x249}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6157, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x24a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x24b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x24c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x24d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x24e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf008, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x24f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x250}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x251}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x252}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf004, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x253}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x254}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf002, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x255}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x256}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x257}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x142d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x258}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x259}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x25a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8bc0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x25b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c3f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x25c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c09, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x25d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x25e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa120, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x25f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa310, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x260}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa420, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x261}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcd3b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x262}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x263}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x65ad, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x264}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x43c7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x265}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x266}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x267}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x827b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x268}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x269}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8273, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x26a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x26b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x26c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd199, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x26d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x26e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf024, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x26f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd15d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x270}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x271}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf021, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x272}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x273}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x274}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1c6, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x275}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x276}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf01c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x277}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd15d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x278}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x279}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf019, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x27a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x27b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x27c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd199, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x27d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x27e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf014, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x27f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x280}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x281}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf011, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x282}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x283}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x284}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x828e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x285}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x286}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x828b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x287}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1e5, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x288}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x289}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf009, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x28a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd191, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x28b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x28c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x28d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x28e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x28f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x290}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd16b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x291}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x292}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x293}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x294}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x295}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1463, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x296}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x297}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f7a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x298}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x299}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f2c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x29a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x29b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x40e7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x29c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x29d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x29e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c0f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x29f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b05, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c0f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b0a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcd3c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x644d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2aa}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x43c7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ab}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ac}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ad}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x82c1, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ae}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2af}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x82b9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf019, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf016, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ba}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2bb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2bc}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf011, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2bd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd13e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2be}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd049, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2bf}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf009, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd049, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ca}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2cb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2cc}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2cd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ce}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0956, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2cf}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2969, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x82f5, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x82eb, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x82e1, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x40c7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2da}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd15c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2db}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2dc}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf01a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2dd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd199, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2de}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2df}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf017, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x40c7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd13e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf010, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd199, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ea}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2eb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x40c7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ec}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ed}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ee}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ef}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd199, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x09a0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2969, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2fa}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x831e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2fb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2fc}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8314, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2fd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2fe}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x830a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ff}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x300}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x40c7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x301}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x302}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x303}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd15d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x304}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x305}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf01a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x306}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x307}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x308}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf017, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x309}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x30a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x40c7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x30b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x30c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x30d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd16b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x30e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x30f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf010, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x310}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x311}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x312}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x313}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x314}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x40c7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x315}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x316}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x317}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x318}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x319}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x31a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x31b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x31c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x31d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1b7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x31e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x31f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x320}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0a39, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x321}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA10E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA10C, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA10A, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA108, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0a12, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA106, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0979, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA104, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x089f, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA102, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0692, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA100, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0f60, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA110, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x001f, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA016, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0020, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA012, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1ff8, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA014, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b0e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ff8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b0e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ff9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b0e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ffa}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ffb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ffc}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ffd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ffe}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1fff}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA164, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0baa, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA166, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c19, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA168, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1293, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA16A, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3fff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA16C, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3fff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA16E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3fff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA170, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3fff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA172, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3fff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA162, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0007, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb820, 7 , 7 , 0x0 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, +}; + +rtk_hwpatch_t rtl8261n_c_algxg_conf[] = { + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8165, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x22 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8167, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x33 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x827E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x68 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8013, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x39 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8ffb, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x14 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8ffa, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x1e , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8ff9, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x1e , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x82D9, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x20 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x82DA, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x00 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x816E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0xab , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8159, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x58 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x815A, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x99 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8139, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x25 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8125, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x67 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8126, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x89 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x827D, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x42 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, +}; + +rtk_hwpatch_t rtl8261n_c_alg_giga_conf[] = { + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x8367, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x5d , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, +}; + +rtk_hwpatch_t rtl8261n_c_normal_conf[] = { + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x817d, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x07 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb516, 6 , 0 , 0x0 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8ffe, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x04 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8fff, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x05 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8132, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x77 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8134, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x88 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x80ca, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x77 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x80cc, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x88 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8062, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x77 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8064, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x88 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x801E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0005, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, +}; + +rtk_hwpatch_t rtl8261n_c_dataram_conf[] = { + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb820, 7 , 7 , 0x0 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb896, 0 , 0 , 0x0 , RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb892, 15, 8 , 0x0 , RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC10B, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xD5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC10C, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xD5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC10D, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xD5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC10E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xD5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC10F, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xD5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC110, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xD5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC149, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x08 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC14A, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x08 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC14B, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x08 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC14C, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x08 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC14D, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x08 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC14E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x08 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC166, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xEE , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC167, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xEE , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC168, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x07 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC169, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x09 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC16A, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x0B , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC16B, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x0D , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC16C, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x13 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC16D, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x0E , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC16E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x11 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC16F, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x14 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC170, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x17 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC171, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x15 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC172, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x10 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC173, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x0B , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC128, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xF7 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC129, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xF7 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC12A, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xF8 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC12B, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xF7 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC12C, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xF6 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC12D, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xF5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC12E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xF2 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC12F, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xF7 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC130, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xF5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC131, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xF2 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC132, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xF0 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC133, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xF1 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC134, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xF4 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC135, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xF7 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb896, 0 , 0 , 0x1 , RTK_PATCH_CMP_W , 0, 0, 0, 0}, +}; + +rtk_hwpatch_t rtl8261n_c_rtct_conf[] = { +}; + diff --git a/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/construct/conf_rtl8264b.c b/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/construct/conf_rtl8264b.c new file mode 100644 index 00000000000..d5cae3fd3ba --- /dev/null +++ b/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/construct/conf_rtl8264b.c @@ -0,0 +1,2177 @@ +/* + * SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved. + */ + +//Date: Thu Dec 15 16:01:01 2022 + +rtk_hwpatch_t rtl8264b_top_conf[] = { + {RTK_PATCH_OP_TOP , 0xf , 2 , 20 , 15, 0 , 0x5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 2 , 21 , 15, 0 , 0x0 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 2 , 22 , 15, 0 , 0x280 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 2 , 23 , 15, 0 , 0x0014, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 3 , 16 , 15, 0 , 0x0300, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 3 , 17 , 15, 0 , 0x01ff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 3 , 18 , 15, 0 , 0x000c, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 3 , 19 , 15, 0 , 0x01ff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 3 , 20 , 15, 0 , 0x0200, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 3 , 21 , 15, 0 , 0x0015, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 3 , 22 , 15, 0 , 0x0200, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 3 , 23 , 15, 0 , 0x0 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 4 , 16 , 15, 0 , 0x0 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 13 , 23 , 8 , 5 , 0x6 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 90 , 18 , 15, 0 , 0xc , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 90 , 19 , 15, 0 , 0xc , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 90 , 20 , 15, 8 , 0x01 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, +}; + +rtk_hwpatch_t rtl8264b_sds_conf[] = { + {RTK_PATCH_OP_TOP , 0xf , 24 , 18 , 15, 0 , 0x881F, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 24 , 19 , 15, 0 , 0x003F, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 24 , 20 , 15, 0 , 0x003F, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 24 , 21 , 15, 0 , 0x003F, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 24 , 22 , 15, 0 , 0x001F, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x06 , 0x0D , 15, 0 , 0x0F00, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x06 , 0x0E , 15, 0 , 0x3F5A, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x07 , 0x10 , 15, 12, 0x8 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x07 , 0x10 , 7 , 0 , 0x3 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x06 , 0x1D , 15, 0 , 0x0600, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x21 , 0x00 , 15, 0 , 0x4902, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x21 , 0x08 , 15, 0 , 0x0FC0, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x21 , 0x09 , 15, 0 , 0x33F0, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x21 , 0x0C , 15, 0 , 0x08BF, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x21 , 0x12 , 15, 0 , 0x8000, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x36 , 0x07 , 15, 0 , 0x04C0, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x36 , 0x08 , 15, 0 , 0x2000, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2E , 0x0B , 15, 0 , 0x2390, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2E , 0x0C , 15, 0 , 0xAA17, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2E , 0x0D , 15, 0 , 0xFE40, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2E , 0x0E , 15, 0 , 0x12F4, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2E , 0x11 , 15, 0 , 0xF2AD, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2E , 0x15 , 15, 0 , 0x7A41, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2E , 0x16 , 15, 0 , 0x0041, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2F , 0x00 , 15, 0 , 0x1F00, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2F , 0x01 , 15, 0 , 0x2800, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2F , 0x02 , 15, 0 , 0x0FC8, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2F , 0x11 , 15, 0 , 0x3000, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2F , 0x13 , 15, 0 , 0xF400, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2F , 0x1E , 15, 0 , 0x0500, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x34 , 0x0B , 15, 0 , 0x2390, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x34 , 0x0C , 15, 0 , 0xA517, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x34 , 0x0D , 15, 0 , 0xFE41, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x34 , 0x0E , 15, 0 , 0x12F4, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x34 , 0x11 , 15, 0 , 0xF2AD, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x34 , 0x15 , 15, 0 , 0x7A41, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x34 , 0x16 , 15, 0 , 0x0041, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x35 , 0x00 , 15, 0 , 0x1F80, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x35 , 0x01 , 15, 0 , 0x0800, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x35 , 0x02 , 15, 0 , 0x0FC8, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x35 , 0x11 , 15, 0 , 0x3001, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x35 , 0x13 , 15, 0 , 0xF400, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x35 , 0x1E , 15, 0 , 0x0100, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2C , 0x0B , 15, 0 , 0x2390, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2C , 0x0C , 15, 0 , 0xA517, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2C , 0x0D , 15, 0 , 0xFE41, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2C , 0x0E , 15, 0 , 0x12F4, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2C , 0x11 , 15, 0 , 0xF2AD, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2C , 0x15 , 15, 0 , 0x7A61, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2C , 0x16 , 15, 0 , 0x0041, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2D , 0x00 , 15, 0 , 0x1F80, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2D , 0x01 , 15, 0 , 0x0800, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2D , 0x02 , 15, 0 , 0x0FC8, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2D , 0x11 , 15, 0 , 0x3001, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2D , 0x13 , 15, 0 , 0xF400, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x2D , 0x1E , 15, 0 , 0x0100, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x28 , 0x0B , 15, 0 , 0x2390, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x28 , 0x0C , 15, 0 , 0xA514, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x28 , 0x0D , 15, 0 , 0xFE43, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x28 , 0x0E , 15, 0 , 0x12F4, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x28 , 0x11 , 15, 0 , 0xF2AD, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x28 , 0x15 , 15, 0 , 0x7A61, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x28 , 0x16 , 15, 0 , 0x0041, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x29 , 0x00 , 15, 0 , 0x1F80, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x29 , 0x01 , 15, 0 , 0x0800, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x29 , 0x02 , 15, 0 , 0x0FC8, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x29 , 0x11 , 15, 0 , 0x3001, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x29 , 0x13 , 15, 0 , 0xF400, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x29 , 0x1E , 15, 0 , 0x0100, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x26 , 0x0B , 15, 0 , 0x2390, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x26 , 0x0C , 15, 0 , 0xA514, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x26 , 0x0D , 15, 0 , 0xFE43, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x26 , 0x0E , 15, 0 , 0x12F4, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x26 , 0x11 , 15, 0 , 0xF2AD, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x26 , 0x15 , 15, 0 , 0x7A41, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x26 , 0x16 , 15, 0 , 0x0041, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x27 , 0x00 , 15, 0 , 0x1F80, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x27 , 0x01 , 15, 0 , 0x0800, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x27 , 0x02 , 15, 0 , 0x0FC8, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x27 , 0x11 , 15, 0 , 0x3001, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x27 , 0x13 , 15, 0 , 0xF400, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x27 , 0x1E , 15, 0 , 0x0100, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x24 , 0x0B , 15, 0 , 0x2390, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x24 , 0x0C , 15, 0 , 0xA514, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x24 , 0x0D , 15, 0 , 0xFE43, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x24 , 0x0E , 15, 0 , 0x12F4, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x24 , 0x11 , 15, 0 , 0xF2AD, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x24 , 0x15 , 15, 0 , 0x7A41, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x24 , 0x16 , 15, 0 , 0x0041, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x25 , 0x00 , 15, 0 , 0x1F80, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x25 , 0x01 , 15, 0 , 0x0800, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x25 , 0x02 , 15, 0 , 0x0FC8, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x25 , 0x11 , 15, 0 , 0x3001, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x25 , 0x13 , 15, 0 , 0xF400, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x25 , 0x1E , 15, 0 , 0x0100, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 24 , 18 , 15, 0 , 0x880D, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 24 , 19 , 15, 0 , 0x0024, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 24 , 20 , 15, 0 , 0x0036, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 24 , 21 , 15, 0 , 0x0035, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 24 , 22 , 15, 0 , 0x001A, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x1F , 0x00 , 15, 0 , 0x001B, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PSDS0 , 0xf , 0x1F , 0x00 , 15, 0 , 0x0000, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 90 , 20 , 7 , 0 , 0x03 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, +}; + +rtk_hwpatch_t rtl8264b_afe_conf[] = { + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbf92, 15, 11, 0x1C , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbfaa, 10, 8 , 0x5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbfae, 8 , 6 , 0x5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbfaa, 12, 11, 0x1 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbf1c, 4 , 4 , 0x1 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbf0e, 5 , 4 , 0x3 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbf1c, 15, 13, 0x5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbf16, 12, 12, 0x0 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbc24, 3 , 2 , 0x1 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbc24, 1 , 0 , 0x1 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbf08, 2 , 0 , 0x6 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbf0c, 5 , 3 , 0x7 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbf0c, 8 , 6 , 0x7 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbf0c, 11, 9 , 0x7 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbf0c, 14, 12, 0x7 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_TOP , 0xf , 90 , 21 , 15, 8 , 0x03 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, +}; + +rtk_hwpatch_t rtl8264b_uc_conf[] = { + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb820, 7 , 7 , 0x0 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbd8a, 5 , 3 , 0x3 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbd8c, 6 , 4 , 0x5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x8060, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 12, 10, 0x3 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x8061, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 13, 0x5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa466, 1 , 1 , 0x1 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x8491, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x1D , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x8018, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 12, 12, 0x1 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x85af, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf85, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85af}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xc7af, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85b1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x85df, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85b3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf86, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85b5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1baf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85b7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8674, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85b9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf86, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85bb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7daf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85bd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x875b, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85bf}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf87, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85c1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x67af, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85c3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8774, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85c5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf85, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85c7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xdc02, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85c9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6957, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85cb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe48f, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85cd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2ce5, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85cf}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8f2d, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85d1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe084, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85d3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x11e1, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85d5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8412, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85d7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf5d, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85d9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x73f6, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85db}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xb01a, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85dd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe08f, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85df}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2ce1, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85e1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8f2d, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85e3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6d, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85e5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6802, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85e7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6938, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85e9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6d, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85eb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6b02, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85ed}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6938, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85ef}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6d, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85f1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6e02, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85f3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6938, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85f5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6d, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85f7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7102, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85f9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6938, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85fb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6d, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85fd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7402, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85ff}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70e5, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8601}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6d, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8603}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7702, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8605}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70e5, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8607}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6d, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8609}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7a02, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x860b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70e5, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x860d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6d, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x860f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7d02, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8611}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70e5, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8613}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd784, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8615}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa2af, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8617}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5eed, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8619}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0286, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x861b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x21af, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x861d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x07ad, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x861f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf8f9, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8621}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfaef, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8623}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x69e0, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8625}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8018, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8627}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xad24, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8629}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x39d4, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x862b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x002e, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x862d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6e, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x862f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0402, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8631}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6938, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8633}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd480, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8635}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x03bf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8637}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x866e, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8639}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0269, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x863b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x38d4, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x863d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x000f, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x863f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf86, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8641}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7102, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8643}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6938, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8645}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf86, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8647}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7102, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8649}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70dc, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x864b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd480, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x864d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0bbf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x864f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x866e, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8651}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0269, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8653}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x38d4, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8655}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x000f, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8657}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf86, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8659}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7102, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x865b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6938, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x865d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf86, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x865f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7102, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8661}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70dc, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8663}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0208, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8665}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1eef, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8667}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x96fe, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8669}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfdfc, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x866b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x04f0, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x866d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbd94, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x866f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x30bd, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8671}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9602, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8673}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8621, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8675}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0254, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8677}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xdcaf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8679}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x03c1, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x867b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0286, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x867d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2102, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x867f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8686, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8681}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf04, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8683}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x41f8, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8685}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfbef, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8687}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x79e0, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8689}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8018, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x868b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xac20, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x868d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x03af, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x868f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8756, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8691}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6b, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8693}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3402, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8695}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70dc, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8697}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6b, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8699}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3102, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x869b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70e5, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x869d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6f, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x869f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4902, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86a1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70dc, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86a3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6f, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86a5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4c02, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86a7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70e5, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86a9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6f, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86ab}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4f02, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86ad}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70e5, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86af}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6b, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86b1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3702, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86b3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70dc, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86b5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6c, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86b7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c02, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86b9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70dc, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86bb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6b, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86bd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3402, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86bf}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70e5, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86c1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1f00, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86c3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe183, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86c5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd4bf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86c7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6bcd, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86c9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0269, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86cb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x38bf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86cd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6bd0, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86cf}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0269, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86d1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x38bf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86d3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6bd3, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86d5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0269, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86d7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x38bf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86d9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6bd6, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86db}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0269, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86dd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x38bf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86df}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6bd9, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86e1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86e3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe5bf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86e5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6bdc, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86e7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86e9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe5bf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86eb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6bdf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86ed}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86ef}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe5bf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86f1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6be2, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86f3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86f5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe5bf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86f7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6f46, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86f9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86fb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xdce1, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86fd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x83d3, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86ff}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6f, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8701}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3a02, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8703}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6938, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8705}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0d14, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8707}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6f, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8709}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4002, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x870b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6938, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x870d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0d12, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x870f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6f, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8711}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3d02, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8713}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6938, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8715}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6f, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8717}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4302, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8719}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70dc, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x871b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0238, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x871d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xb5bf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x871f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6bd9, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8721}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8723}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xdcbf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8725}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6bdc, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8727}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8729}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xdcbf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x872b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6bdf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x872d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x872f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xdcbf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8731}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6be2, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8733}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8735}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xdcbf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8737}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6b34, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8739}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x873b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xdcbf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x873d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6b37, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x873f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8741}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe5bf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8743}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6f4f, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8745}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8747}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xdcbf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8749}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6b31, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x874b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x874d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xdcbf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x874f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6f4c, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8751}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8753}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xdcef, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8755}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x97ff, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8757}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfc04, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8759}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xac2f, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x875b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x03af, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x875d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b2a, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x875f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x020e, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8761}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x95af, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8763}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b3f, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8765}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xee84, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8767}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3c00, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8769}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6c, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x876b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c02, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x876d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70e5, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x876f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf01, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8771}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0300, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8773}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb818, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5d6d, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb81a, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5eea, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb81c, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x07aa, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb81e, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x03be, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb850, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x043e, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb852, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b26, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb878, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x00fd, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb884, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb832, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x007f, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, +}; + +rtk_hwpatch_t rtl8264b_uc2_conf[] = { + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb820, 7 , 7 , 0x1 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb87c, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8acf, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb87e, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf8a, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8acf}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe7af, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ad1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8b40, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ad3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf8b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ad5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4caf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ad7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8b6a, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ad9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf8b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8adb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xb5af, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8add}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8bd1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8adf}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf8c, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ae1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x04af, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ae3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8c12, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ae5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf67, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ae7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6302, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ae9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x65f5, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8aeb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xef31, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8aed}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf67, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8aef}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6002, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8af1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x65f5, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8af3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1e31, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8af5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xac38, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8af7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x19bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8af9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x676c, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8afb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0265, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8afd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf5ef, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8aff}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x31bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b01}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6769, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b03}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0265, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b05}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf51e, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b07}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x31ac, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b09}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x380c, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b0b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xee89, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b0d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2c02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b0f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xae0a, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b11}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xee89, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b13}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2c00, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b15}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xae04, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b17}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xee89, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b19}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2c01, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b1b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf8f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b1d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd5e1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b1f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x892c, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b21}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1a91, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b23}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xdbbf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b25}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x67cf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b27}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0265, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b29}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf51f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b2b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x001f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b2d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x221b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b2f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x45ad, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b31}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2705, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b33}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe187, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b35}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x06ae, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b37}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x03e1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b39}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8707, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b3b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf2d, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b3d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1a02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b3f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8c1e, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b41}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x028c, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b43}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7b02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b45}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x224f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b47}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf40, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b49}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xb8ac, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b4b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2f0f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b4d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0210, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b4f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x62bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b51}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6d36, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b53}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0265, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b55}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf5e5, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b57}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8fde, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b59}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf10, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b5b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4ae1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b5d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8fde, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b5f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6d, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b61}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3602, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b63}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x65d6, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b65}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf10, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b67}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x59e1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b69}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8fdd, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b6b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa100, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b6d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0dbf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b6f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6d36, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b71}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0265, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b73}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf5e5, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b75}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8fdc, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b77}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xee8f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b79}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xdd01, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b7b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6d, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b7d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3602, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b7f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6f77, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b81}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf86, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b83}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xc7e1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b85}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x892c, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b87}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4903, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b89}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1a91, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b8b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xef69, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b8d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xdbbf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b8f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x67cf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b91}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0265, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b93}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf51f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b95}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x001f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b97}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x22ef, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b99}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x741b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b9b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x45ad, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b9d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2711, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b9f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf86, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ba1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd0d0, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ba3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x00e1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ba5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8fdc, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ba7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6d, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ba9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3602, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bab}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x65d6, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bad}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf35, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8baf}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x46af, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bb1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3527, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bb3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x026f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bb5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6eee, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bb7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8fdd, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bb9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x00bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bbb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8d31, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bbd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x026f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bbf}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6ebf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bc1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8d40, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bc3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x026f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bc5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6ebf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bc7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8d46, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bc9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x026f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bcb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6eaf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bcd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x36a9, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bcf}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf8ef, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bd1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x49f8, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bd3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6e, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bd5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xc202, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bd7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x65f5, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bd9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xad28, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bdb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13e1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bdd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8a4e, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bdf}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xad28, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8be1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0502, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8be3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5d65, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8be5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xae0e, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8be7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x025c, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8be9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1202, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8beb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8cc5, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bed}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xae06, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bef}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x025b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bf1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf302, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bf3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8d0d, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bf5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe087, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bf7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x17f6, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bf9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x27e4, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bfb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8717, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bfd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfcef, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bff}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x94fc, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c01}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x04a1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c03}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0103, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c05}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x028c, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c07}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe9e0, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c09}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8a02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c0b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xef23, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c0d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf5c, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c0f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xdeac, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c11}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5003, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c13}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf61, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c15}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0d02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c17}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8d0d, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c19}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf61, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c1b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33f8, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c1d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfafb, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c1f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xef79, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c21}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfbbf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c23}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6766, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c25}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0265, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c27}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf5ad, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c29}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2810, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c2b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xad30, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c2d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x05d7, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c2f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0002, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c31}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xae16, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c33}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xad32, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c35}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x24d7, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c37}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0003, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c39}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xae0e, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c3b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xad31, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c3d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x05d7, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c3f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c41}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xae06, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c43}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xad33, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c45}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x14d7, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c47}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0001, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c49}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf8f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c4b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xdf4f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c4d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0008, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c4f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1a97, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c51}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd78c, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c53}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x63d6, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c55}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8c7b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c57}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0265, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c59}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3bff, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c5b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xef97, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c5d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfffe, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c5f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfc04, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c61}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x206b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c63}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0e20, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c65}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6b11, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c67}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x206b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c69}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1420, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c6b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6b17, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c6d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x206b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c6f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2020, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c71}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6b23, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c73}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x206b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c75}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2600, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c77}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6b29, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c79}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf8fa, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c7b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xef69, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c7d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6d, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c7f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbd02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c81}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x65f5, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c83}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xad28, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c85}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0ebf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c87}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8d34, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c89}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x026f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c8b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x77bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c8d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8d31, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c8f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x026f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c91}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x77ae, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c93}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2ad1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c95}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0fbf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c97}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8d37, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c99}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0265, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c9b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd6bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c9d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8d3a, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c9f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x026f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ca1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6ed1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ca3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x00bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ca5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8d3d, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ca7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0265, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ca9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd6bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cab}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8d40, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cad}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x026f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8caf}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x77d1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cb1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x00bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cb3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8d43, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cb5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0265, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cb7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd6bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cb9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8d46, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cbb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x026f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cbd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x77ef, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cbf}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x96fe, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cc1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfc04, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cc3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf8ef, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cc5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x49f8, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cc7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6d, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cc9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbd02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ccb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x65f5, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ccd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xac28, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ccf}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x12bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cd1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6be6, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cd3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0265, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cd5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf5e5, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cd7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8fd8, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cd9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cdb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf202, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cdd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x65f5, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cdf}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe58f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ce1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd9fc, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ce3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xef94, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ce5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfc04, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ce7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf8ef, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ce9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x49f8, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ceb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6d, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ced}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbd02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cef}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x65f5, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cf1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xac28, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cf3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x12e1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cf5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8fda, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cf7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cf9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe602, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cfb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x65d6, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cfd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe18f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cff}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xdbbf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d01}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6bf2, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d03}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0265, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d05}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd6fc, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d07}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xef94, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d09}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfc04, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d0b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf8ef, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d0d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x49f8, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d0f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6d, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d11}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbd02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d13}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x65f5, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d15}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xac28, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d17}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x12e1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d19}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8fd8, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d1b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d1d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe602, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d1f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x65d6, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d21}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe18f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d23}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd9bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d25}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6bf2, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d27}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0265, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d29}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd6fc, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d2b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xef94, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d2d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfc04, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d2f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x77bd, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d31}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6c66, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d33}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbd6c, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d35}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x30bd, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d37}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5444, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d39}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbd54, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d3b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x85bd, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d3d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5e55, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d3f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbd54, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d41}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa7bd, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d43}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5cbb, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d45}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbd5c, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d47}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb85e, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2d07, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb860, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x40b5, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb862, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1047, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb864, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3504, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb886, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x36A6, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb888, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x613d, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb88a, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5cd9, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb88c, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x610a, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb838, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x00ff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb820, 7 , 7 , 0x0 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, +}; + +rtk_hwpatch_t rtl8264b_nctl0_conf[] = { + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb820, 7 , 7 , 0x1 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA016, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA012, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA014, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8010, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8015, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8020, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x802a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8030, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8035, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8046, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x806b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd707, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x10}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x606f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x11}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x12}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x801a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x13}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x14}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd707, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x15}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x606f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x16}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x17}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x801a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x18}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x19}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce10, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcf01, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd705, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4004, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcf02, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd719, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x20}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3bb7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x21}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8024, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x22}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x23}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd704, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x24}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x406e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x25}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x26}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x12bd, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x27}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x28}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x12e3, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x29}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xab80, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd500, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xc402, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x004a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x30}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8b80, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x31}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd500, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x32}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x33}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0108, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x34}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c0f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x35}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x090f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x36}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c0f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x37}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0a03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x38}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd004, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x39}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1c1, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x401c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce00, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd500, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x801a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x40}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd501, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x41}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce01, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x42}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x43}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x44}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0aa9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x45}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd500, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x46}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x47}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2a69, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x48}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8056, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x49}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3f48, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8058, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3f4b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x805a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x618c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3f40, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x805c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x50}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3f43, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x51}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x805e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x52}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x616b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x53}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6187, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x54}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x55}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcc8f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x56}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x57}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcc8d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x58}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf008, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x59}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcc8b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcc89, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf004, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcc87, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf002, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcc91, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x60}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x61}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b9a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x62}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x63}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xca80, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x64}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x65}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0ba0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x66}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xca00, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x67}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd504, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x68}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x69}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1658, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa208, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0a88, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0d91, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA026, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0d90, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA024, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1657, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA022, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0aa1, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA020, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0047, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA006, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0049, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA004, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x12b9, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA002, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0be5, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA000, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1811, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA008, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xff00, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA016, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA012, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0ff8, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA014, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xc483, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x0ff8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xc483, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xff9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xffa}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xffb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xffc}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xffd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xffe}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xfff}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA152, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1a83, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA154, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1d29, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA156, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3fff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA158, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3fff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA15A, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3fff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA15C, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3fff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA15E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3fff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA160, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3fff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA150, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0003, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb820, 7 , 7 , 0x0 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, +}; + +rtk_hwpatch_t rtl8264b_nctl1_conf[] = { +}; + +rtk_hwpatch_t rtl8264b_nctl2_conf[] = { + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb820, 7 , 7 , 0x1 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA016, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0020, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA012, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA014, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8010, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8022, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8029, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8085, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x808c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8093, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8281, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x829a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x10}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x11}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8370, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x12}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x13}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd707, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x14}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x416f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x15}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x16}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd05a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x17}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa501, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x18}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x19}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd701, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5fbd, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8501, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0427, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x20}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x040b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x21}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8501, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x22}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd707, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x23}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x406f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x24}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x25}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x01d8, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x26}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x27}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x01cb, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x28}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd705, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x29}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3fa7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8030, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd75f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x699c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1340, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd704, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x30}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4066, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x31}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x800a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x32}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf002, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x33}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x34}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd705, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x35}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x61b4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x36}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd704, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x37}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x609f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x38}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6150, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x39}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2d71, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8043, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cf0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x05a0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x40}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x41}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13b1, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x42}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x43}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x44}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8220, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x45}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c30, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x46}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0410, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x47}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x48}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x800a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x49}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x81a0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8302, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8480, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8684, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8203, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x50}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8340, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x51}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x52}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaa10, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x53}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8b07, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x54}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x55}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x60cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x56}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x60f1, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x57}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6113, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x58}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6135, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x59}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6157, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce0b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce0b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf008, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce0a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x60}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x61}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce0a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x62}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf004, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x63}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce09, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x64}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf002, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x65}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce09, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x66}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x67}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x68}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa204, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x69}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13e4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xab08, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcda0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd705, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x40de, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x70}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd162, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x71}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd045, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x72}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf10, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x73}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x74}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13b1, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x75}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9f10, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x76}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x77}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13b1, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x78}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x79}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x607a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x7a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x7b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13b1, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x7c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9f10, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x7d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x7e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x7f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8210, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x80}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa210, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x81}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x82}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x83}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1340, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x84}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x85}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x86}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8df8, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x87}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8370, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x88}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x89}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x8a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x01c1, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x8b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x8c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x8d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8df8, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x8e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8370, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x8f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x90}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x91}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x009e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x92}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x93}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x94}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x809e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x95}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x96}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x809b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x97}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1bf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x98}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd06d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x99}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x9a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1dd, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x9b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd06d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x9c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x9d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd199, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x9e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd06e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x9f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5fba, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd05a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x60cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x60f1, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6113, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6135, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xaa}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6157, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xab}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xac}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xad}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xae}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xaf}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf008, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf004, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf002, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13e4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xba}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xbb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0ccf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xbc}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b40, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xbd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c3f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xbe}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c24, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xbf}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa340, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1433, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa110, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13ec, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8110, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x143c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa304, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xca}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa8c0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xcb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8810, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xcc}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xcd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa120, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xce}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa310, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xcf}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cfc, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0224, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0ca0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0480, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa340, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd162, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xda}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xdb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xdc}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5fba, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xdd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8840, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xde}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1c4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xdf}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd045, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5fba, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6127, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f3b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x88c0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x800a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xea}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8120, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xeb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8350, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xec}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x84a0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xed}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffb6, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xee}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xb920, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xef}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcd33, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7fb4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9920, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6065, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f94, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xfa}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffee, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xfb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xb820, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xfc}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xfd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xfe}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xff}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7fa5, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x100}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9820, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x101}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x800a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x102}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8120, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x103}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x104}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1433, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x105}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa108, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x106}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x107}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13ec, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x108}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8108, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x109}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x10a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x143c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x10b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa2fc, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x10c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa304, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x10d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8880, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x10e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cc0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x10f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0440, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x110}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcd34, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x111}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x112}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x113}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cc0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x114}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b80, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x115}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xac3f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x116}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c38, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x117}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0d08, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x118}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x119}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa810, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x11a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x11b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa120, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x11c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa480, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x11d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa604, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x11e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x11f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x120}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8125, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x121}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x122}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd049, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x123}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x124}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd19f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x125}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd049, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x126}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x127}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x128}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x129}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x63f4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x12a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x12b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f7a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x12c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x12d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4368, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x12e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x12f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x130}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cc0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x131}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b40, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x132}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8c3f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x133}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8d38, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x134}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x135}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x136}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x137}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8141, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x138}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x139}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x813e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x13a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1f4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x13b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x13c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x13d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1b7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x13e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x13f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x140}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1c6, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x141}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x142}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x143}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x144}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x145}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6074, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x146}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x147}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f7a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x148}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x149}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x14a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x14b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4056, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x14c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf004, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x14d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x14e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x61fc, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x14f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfff9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x150}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x151}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x152}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x153}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x154}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4070, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x155}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x156}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x820e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x157}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x158}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x159}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xae80, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x15a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x15b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x15c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x820e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x15d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x15e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd05a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x15f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x160}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x60cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x161}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x60f1, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x162}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6113, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x163}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6135, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x164}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6157, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x165}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x166}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x167}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x168}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x169}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf008, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x16a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x16b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x16c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x16d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf004, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x16e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x16f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf002, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x170}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x171}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x172}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13e4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x173}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x174}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x175}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0ccf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x176}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b40, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x177}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c3f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x178}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c24, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x179}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x17a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa340, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x17b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x17c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1433, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x17d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa110, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x17e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x17f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13ec, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x180}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8110, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x181}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x182}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x143c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x183}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa304, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x184}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa8c0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x185}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8810, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x186}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x187}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa120, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x188}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa310, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x189}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cfc, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x18a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0224, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x18b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0ca0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x18c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0480, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x18d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8604, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x18e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcd35, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x18f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd162, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x190}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x191}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x192}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x193}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x194}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5fba, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x195}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8840, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x196}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1c4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x197}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd045, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x198}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x199}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x19a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x19b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5fba, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x19c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x19d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6127, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x19e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x19f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f3b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x88c0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x800a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8120, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8350, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x84a0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffb8, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbb80, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1aa}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5fb4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ab}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xb920, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ac}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcd36, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ad}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ae}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1af}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7fb4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9920, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9b80, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6065, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f94, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffe8, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xb820, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ba}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1bb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1bc}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1bd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7fa5, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1be}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9820, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1bf}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x800a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8120, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1433, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa108, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13ec, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8108, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x143c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa2fc, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ca}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa304, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1cb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8880, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1cc}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cc0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1cd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0440, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ce}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcd37, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1cf}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cc0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b80, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xac3f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c38, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0d08, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa810, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa120, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1da}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa480, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1db}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa604, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1dc}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1dd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1de}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x81e8, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1df}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x81e5, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ea}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1eb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ec}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x141a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ed}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ee}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f7a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ef}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f28, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cc0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b40, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8c3f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8d38, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1fa}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8204, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1fb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1fc}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8201, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1fd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd199, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1fe}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ff}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x200}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x201}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x202}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x203}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd189, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x204}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x205}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x206}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x207}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x208}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x141a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x209}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x20a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f7a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x20b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x20c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f28, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x20d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x20e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x20f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c0f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x210}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b05, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x211}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x212}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x213}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x60cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x214}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x60f1, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x215}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6113, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x216}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6135, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x217}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6157, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x218}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x219}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce08, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x21a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x21b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce08, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x21c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf008, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x21d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce08, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x21e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x21f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce08, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x220}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf004, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x221}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce08, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x222}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf002, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x223}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce08, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x224}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x225}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13e4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x226}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa180, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x227}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcd38, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x228}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x229}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x22a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x823e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x22b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x22c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8236, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x22d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x22e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x22f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x230}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x231}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf013, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x232}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd100, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x233}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd049, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x234}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf010, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x235}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x236}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x237}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1b7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x238}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd049, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x239}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x23a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd100, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x23b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x23c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf008, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x23d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x23e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x23f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x240}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x241}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x242}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd199, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x243}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x244}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd13b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x245}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd055, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x246}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x247}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x248}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x249}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x141a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x24a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x24b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f7b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x24c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa302, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x24d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x24e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x24f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x250}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x141a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x251}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x252}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f7a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x253}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x254}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f28, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x255}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x256}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x257}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c3f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x258}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c12, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x259}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x25a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x25b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x25c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8270, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x25d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x25e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8268, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x25f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x260}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x261}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd199, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x262}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x263}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf013, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x264}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd100, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x265}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x266}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf010, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x267}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x268}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x269}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x26a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x26b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x26c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd100, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x26d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd040, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x26e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf008, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x26f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x270}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x271}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd199, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x272}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x273}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x274}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd16b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x275}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x276}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x277}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x278}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x279}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x141a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x27a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x27b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f7a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x27c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x27d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f2a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x27e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x27f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x085e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x280}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x281}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x282}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcb0a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x283}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cc7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x284}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x285}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x286}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x287}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4127, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x288}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x289}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x28a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c0f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x28b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b05, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x28c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c38, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x28d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0d28, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x28e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x28f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf008, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x290}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x291}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x292}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c0f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x293}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b0a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x294}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c38, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x295}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0d18, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x296}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x297}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x298}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0f45, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x299}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x29a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x646d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x29b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x29c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x82b4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x29d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x29e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x82aa, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x29f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x40c7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd100, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd049, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf01a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd049, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf017, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2aa}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x40c7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ab}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ac}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ad}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd100, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ae}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd049, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2af}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf010, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x40c7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ba}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2bb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2bc}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2bd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2be}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2bf}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x141a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f7a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f29, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x60cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x60f1, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ca}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6113, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2cb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6135, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2cc}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6157, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2cd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ce}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2cf}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf008, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf004, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf002, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2da}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13e4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2db}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2dc}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2dd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8bc0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2de}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c3f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2df}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c09, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa120, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa310, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa420, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcd3b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x65ad, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x43c7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ea}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x82fe, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2eb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ec}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x82f6, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ed}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ee}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ef}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd199, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f1}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf024, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f2}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd15d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f3}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f4}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf021, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f5}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f6}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f7}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1c6, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf01c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2fa}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd15d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2fb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2fc}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf019, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2fd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2fe}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ff}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd199, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x300}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x301}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf014, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x302}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x303}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x304}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf011, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x305}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x306}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x307}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8311, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x308}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x309}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x830e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x30a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1e5, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x30b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x30c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf009, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x30d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd191, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x30e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x30f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x310}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x311}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x312}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x313}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd16b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x314}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x315}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x316}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x317}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x318}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x141a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x319}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x31a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f7a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x31b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x31c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f2c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x31d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x31e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x40e7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x31f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x320}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x321}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c0f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x322}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b05, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x323}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x324}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x325}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x326}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x327}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c0f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x328}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b0a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x329}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x32a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcd3c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x32b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x32c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x644d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x32d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x43c7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x32e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x32f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x330}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8344, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x331}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x332}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x833c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x333}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x334}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x335}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x336}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x337}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf019, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x338}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x339}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x33a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf016, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x33b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x33c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x33d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x33e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x33f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf011, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x340}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd13e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x341}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd049, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x342}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x343}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x344}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x345}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x346}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x347}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf009, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x348}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x349}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd049, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x34a}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x34b}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x34c}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x34d}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x34e}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x34f}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x350}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x351}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x093a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x352}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA10E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0883, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA10C, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0f32, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA10A, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0676, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA108, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x00fa, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA106, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x021d, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA104, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x12fe, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA102, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x01ca, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA100, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x047f, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA110, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x00ff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA016, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0020, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA012, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1ff8, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA014, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd13e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ff8}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd15c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ff9}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd16b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ffa}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd15d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ffb}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b0e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ffc}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b0e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ffd}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b0e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ffe}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1fff}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA164, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0972, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA166, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0968, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA168, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0a0b, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA16A, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0a01, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA16C, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b8a, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA16E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0bf9, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA170, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x125c, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA172, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3fff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA162, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x007F, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb820, 7 , 7 , 0x0 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, +}; + +rtk_hwpatch_t rtl8264b_algxg_conf[] = { + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x815B, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x75 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x80CD, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x25 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8065, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x15 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8175, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0xa2 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8176, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0xc5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8077, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x40 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8078, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0xcc , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8969, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x0f , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8957, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x2C , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8959, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x15 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x895A, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x3E , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x895F, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x1E , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8165, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x22 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x827E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x68 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8167, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x33 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8013, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x39 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8fd7, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x14 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8fd6, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x1e , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8fd5, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x1e , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x82D9, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x20 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x82DA, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x00 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x816E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0xab , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8159, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x58 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x815A, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x99 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8139, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x25 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8125, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x67 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8126, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x89 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x827D, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x42 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, +}; + +rtk_hwpatch_t rtl8264b_alg_giga_conf[] = { + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80b8, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x4d , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80b9, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0xcc , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80ba, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x0 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80bb, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 13, 8 , 0x0 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80bc, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x37 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80bd, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 12, 8 , 0x0c , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80be, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0xBB , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80bf, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0xca , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80c0, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x45 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80c2, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x3b , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80cc, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x16 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80cd, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 10, 8 , 0x4 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80ce, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x0 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80cf, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 13, 8 , 0x0 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80d0, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x53 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80d1, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 12, 8 , 0x0a , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80d2, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0xB9 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80d3, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0xd0 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80d4, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x4a , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80d6, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x35 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80a4, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x0d , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80a5, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0xa4 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80a6, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x59 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80a7, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 13, 8 , 0x05 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80a8, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0xab , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80a9, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 12, 8 , 0x0b , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80aa, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0xef , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80ab, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0xae , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80ac, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0xdf , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80ae, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x28 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x8367, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x5d , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, +}; + +rtk_hwpatch_t rtl8264b_normal_conf[] = { + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbd92, 15, 0 , 0x002e, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbd94, 15, 0 , 0x8003, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbd96, 3 , 0 , 0xf , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbd96, 3 , 0 , 0x0 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbd94, 15, 0 , 0x800b, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbd96, 3 , 0 , 0xf , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbd96, 3 , 0 , 0x0 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x817D, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x07 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x8426, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x46 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x8428, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x46 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x84de, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x84e0, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x00fc, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x84e2, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf61a, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x84e4, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x58 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x84e6, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x84e8, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x00fc, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x84ea, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf61a, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x84ec, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x58 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x84ee, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x84f0, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x00fc, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x84f2, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf61a, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x84f4, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x58 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xae32, 5 , 5 , 0x1 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x8018, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 12, 12, 0x1 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8fdf, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 0 , 0x0496, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8fe1, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 0 , 0x03a5, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8fe3, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 0 , 0x02e5, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8fe5, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 0 , 0x020d, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8fe7, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 0 , 0x0496, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8fe9, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 0 , 0x03a5, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8feb, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 0 , 0x02e5, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8fed, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 0 , 0x020d, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8fef, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 0 , 0x0496, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8ff1, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 0 , 0x03a5, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8ff3, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 0 , 0x02e5, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8ff5, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 0 , 0x020d, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8ff7, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 0 , 0x0496, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8ff9, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 0 , 0x03a5, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8ffb, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 0 , 0x02e5, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8ffd, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 0 , 0x020d, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb516, 6 , 0 , 0x0 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8fda, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x04 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8fdb, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x05 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8132, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x77 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8134, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x88 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x80ca, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x77 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x80cc, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x88 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8062, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x77 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8064, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x88 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x801E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0012, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, +}; + +rtk_hwpatch_t rtl8264b_dataram_conf[] = { + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb820, 7 , 7 , 0x0 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb896, 0 , 0 , 0x0 , RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb892, 15, 8 , 0x0 , RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC037, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x33 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC038, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x2A , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC039, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x25 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC03A, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x20 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC03B, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x1C , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC03C, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x17 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC03D, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x13 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC075, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xA1 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC076, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xB1 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC077, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x2E , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC078, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x55 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC079, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x19 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC07A, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xDC , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC07B, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xA0 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC10B, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xD5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC10C, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xD5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC10D, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xD5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC10E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xD5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC10F, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xD5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC110, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xD5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC149, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x08 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC14A, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x08 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC14B, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x08 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC14C, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x08 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC14D, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x08 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC14E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x08 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC166, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xEE , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC167, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xEE , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC168, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x07 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC169, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x09 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC16A, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x0B , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC16B, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x0D , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC16C, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x13 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC16D, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x0E , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC16E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x11 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC16F, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x14 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC170, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x17 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC171, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x15 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC172, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x10 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC173, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x0B , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC128, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xF7 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC129, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xF7 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC12A, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xF8 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC12B, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xF7 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC12C, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xF6 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC12D, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xF5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC12E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xF2 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC12F, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xF7 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC130, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xF5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC131, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xF2 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC132, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xF0 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC133, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xF1 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC134, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xF4 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC135, RTK_PATCH_CMP_W , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xF7 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, + {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb896, 0 , 0 , 0x1 , RTK_PATCH_CMP_W , 0, 0, 0, 0}, +}; + +rtk_hwpatch_t rtl8264b_rtct_conf[] = { +}; + diff --git a/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/error.h b/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/error.h new file mode 100644 index 00000000000..d99a996f8c0 --- /dev/null +++ b/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/error.h @@ -0,0 +1,165 @@ +/* + * SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved. + */ + +#ifndef __COMMON_ERROR_H__ +#define __COMMON_ERROR_H__ + +/* + * Include Files + */ +#if defined(RTK_PHYDRV_IN_LINUX) + #include "type.h" +#else + #include +#endif +/* + * Data Type Declaration + */ +typedef enum rt_error_common_e +{ + RT_ERR_FAILED = -1, /* General Error */ + + /* 0x0000xxxx for common error code */ + RT_ERR_OK = 0, /* 0x00000000, OK */ + RT_ERR_INPUT = 0xF001, /* 0x0000F001, invalid input parameter */ + RT_ERR_UNIT_ID, /* 0x0000F002, invalid unit id */ + RT_ERR_PORT_ID, /* 0x0000F003, invalid port id */ + RT_ERR_PORT_MASK, /* 0x0000F004, invalid port mask */ + RT_ERR_PORT_LINKDOWN, /* 0x0000F005, link down port status */ + RT_ERR_ENTRY_INDEX, /* 0x0000F006, invalid entry index */ + RT_ERR_NULL_POINTER, /* 0x0000F007, input parameter is null pointer */ + RT_ERR_QUEUE_ID, /* 0x0000F008, invalid queue id */ + RT_ERR_QUEUE_NUM, /* 0x0000F009, invalid queue number */ + RT_ERR_BUSYWAIT_TIMEOUT, /* 0x0000F00a, busy watting time out */ + RT_ERR_MAC, /* 0x0000F00b, invalid mac address */ + RT_ERR_OUT_OF_RANGE, /* 0x0000F00c, input parameter out of range */ + RT_ERR_CHIP_NOT_SUPPORTED, /* 0x0000F00d, functions not supported by this chip model */ + RT_ERR_SMI, /* 0x0000F00e, SMI error */ + RT_ERR_NOT_INIT, /* 0x0000F00f, The module is not initial */ + RT_ERR_CHIP_NOT_FOUND, /* 0x0000F010, The chip can not found */ + RT_ERR_NOT_ALLOWED, /* 0x0000F011, actions not allowed by the function */ + RT_ERR_DRIVER_NOT_FOUND, /* 0x0000F012, The driver can not found */ + RT_ERR_SEM_LOCK_FAILED, /* 0x0000F013, Failed to lock semaphore */ + RT_ERR_SEM_UNLOCK_FAILED, /* 0x0000F014, Failed to unlock semaphore */ + RT_ERR_THREAD_EXIST, /* 0x0000F015, Thread exist */ + RT_ERR_THREAD_CREATE_FAILED, /* 0x0000F016, Thread create fail */ + RT_ERR_FWD_ACTION, /* 0x0000F017, Invalid forwarding Action */ + RT_ERR_IPV4_ADDRESS, /* 0x0000F018, Invalid IPv4 address */ + RT_ERR_IPV6_ADDRESS, /* 0x0000F019, Invalid IPv6 address */ + RT_ERR_PRIORITY, /* 0x0000F01a, Invalid Priority value */ + RT_ERR_FID, /* 0x0000F01b, invalid fid */ + RT_ERR_ENTRY_NOTFOUND, /* 0x0000F01c, specified entry not found */ + RT_ERR_DROP_PRECEDENCE, /* 0x0000F01d, invalid drop precedence */ + RT_ERR_NOT_FINISH, /* 0x0000F01e, Action not finish, still need to wait */ + RT_ERR_TIMEOUT, /* 0x0000F01f, Time out */ + RT_ERR_REG_ARRAY_INDEX_1, /* 0x0000F020, invalid index 1 of register array */ + RT_ERR_REG_ARRAY_INDEX_2, /* 0x0000F021, invalid index 2 of register array */ + RT_ERR_ETHER_TYPE, /* 0x0000F022, invalid ether type */ + RT_ERR_MBUF_PKT_NOT_AVAILABLE, /* 0x0000F023, mbuf->packet is not available */ + RT_ERR_QOS_INVLD_RSN, /* 0x0000F024, invalid pkt to CPU reason */ + RT_ERR_CB_FUNCTION_EXIST, /* 0x0000F025, Callback function exist */ + RT_ERR_CB_FUNCTION_FULL, /* 0x0000F026, Callback function number is full */ + RT_ERR_CB_FUNCTION_NOT_FOUND, /* 0x0000F027, Callback function can not found */ + RT_ERR_TBL_FULL, /* 0x0000F028, The table is full */ + RT_ERR_TRUNK_ID, /* 0x0000F029, invalid trunk id */ + RT_ERR_TYPE, /* 0x0000F02a, invalid type */ + RT_ERR_ENTRY_EXIST, /* 0x0000F02b, entry exists */ + RT_ERR_CHIP_UNDEFINED_VALUE, /* 0x0000F02c, chip returned an undefined value */ + RT_ERR_EXCEEDS_CAPACITY, /* 0x0000F02d, exceeds the capacity of hardware */ + RT_ERR_ENTRY_REFERRED, /* 0x0000F02e, entry is still being referred */ + RT_ERR_OPER_DENIED, /* 0x0000F02f, operation denied */ + RT_ERR_PORT_NOT_SUPPORTED, /* 0x0000F030, functions not supported by this port */ + RT_ERR_SOCKET, /* 0x0000F031, socket error */ + RT_ERR_MEM_ALLOC, /* 0x0000F032, insufficient memory resource */ + RT_ERR_ABORT, /* 0x0000F033, operation aborted */ + RT_ERR_DEV_ID, /* 0x0000F034, invalid device id */ + RT_ERR_DRIVER_NOT_SUPPORTED, /* 0x0000F035, functions not supported by this driver */ + RT_ERR_NOT_SUPPORTED, /* 0x0000F036, functions not supported */ + RT_ERR_SER, /* 0x0000F037, ECC or parity error */ + RT_ERR_MEM_NOT_ALIGN, /* 0x0000F038, memory address is not aligned */ + RT_ERR_SEM_FAKELOCK_OK, /* 0x0000F039, attach thread lock a semaphore which was already locked */ + RT_ERR_CHECK_FAILED, /* 0x0000F03a, check result is failed */ + + RT_ERR_COMMON_END = 0xFFFF /* The symbol is the latest symbol of common error */ +} rt_error_common_t; + +/* + * Macro Definition + */ +#define RT_PARAM_CHK(expr, errCode)\ +do {\ + if ((int32)(expr)) {\ + return errCode; \ + }\ +} while (0) + +#define RT_PARAM_CHK_EHDL(expr, errCode, err_hdl)\ +do {\ + if ((int32)(expr)) {\ + {err_hdl}\ + return errCode; \ + }\ +} while (0) + +#define RT_INIT_CHK(state)\ +do {\ + if (INIT_COMPLETED != (state)) {\ + return RT_ERR_NOT_INIT;\ + }\ +} while (0) + +#define RT_INIT_REENTRY_CHK(state)\ +do {\ + if (INIT_COMPLETED == (state)) {\ + osal_printf(" %s had already been initialized!\n", __FUNCTION__);\ + return RT_ERR_OK;\ + }\ +} while (0) + +#define RT_INIT_REENTRY_CHK_NO_WARNING(state)\ + do {\ + if (INIT_COMPLETED == (state)) {\ + return RT_ERR_OK;\ + }\ + } while (0) + +#define RT_ERR_CHK(op, ret)\ +do {\ + if ((ret = (op)) != RT_ERR_OK)\ + return ret;\ +} while(0) + +#define RT_ERR_HDL(op, errHandle, ret)\ +do {\ + if ((ret = (op)) != RT_ERR_OK)\ + goto errHandle;\ +} while(0) + +#define RT_ERR_CHK_EHDL(op, ret, err_hdl)\ +do {\ + if ((ret = (op)) != RT_ERR_OK)\ + {\ + {err_hdl}\ + return ret;\ + }\ +} while(0) + +#define RT_NULL_HDL(pointer, err_label)\ +do {\ + if (NULL == (pointer)) {\ + goto err_label;\ + }\ +} while (0) + +#define RT_ERR_VOID_CHK(op, ret)\ +do {\ + if ((ret = (op)) != RT_ERR_OK) {\ + osal_printf("Fail in %s %d, ret %x!\n", __FUNCTION__, __LINE__, ret);\ + return ;}\ +} while(0) + +#endif /* __COMMON_ERROR_H__ */ + diff --git a/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/phy_patch.c b/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/phy_patch.c new file mode 100644 index 00000000000..f9af3ffe022 --- /dev/null +++ b/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/phy_patch.c @@ -0,0 +1,179 @@ +/* + * SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved. + */ + +/* + * Include Files + */ +#if defined(RTK_PHYDRV_IN_LINUX) + #include "rtk_osal.h" +#else + #include + #include + #include + #include + #include +#endif + +/* + * Function Declaration + */ +uint8 phy_patch_op_translate(uint8 patch_mode, uint8 patch_op, uint8 compare_op) +{ + if (patch_mode != PHY_PATCH_MODE_CMP) + { + return patch_op; + } + else + { + switch (compare_op) + { + case RTK_PATCH_CMP_WS: + return RTK_PATCH_OP_SKIP; + case RTK_PATCH_CMP_W: + case RTK_PATCH_CMP_WC: + case RTK_PATCH_CMP_SWC: + default: + return RTK_PATCH_OP_TO_CMP(patch_op, compare_op); + } + } +} + +int32 phy_patch_op(rt_phy_patch_db_t *pPhy_patchDb, uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_op, uint16 portmask, uint16 pagemmd, uint16 addr, uint8 msb, uint8 lsb, uint16 data, uint8 patch_mode) +{ + rtk_hwpatch_t op; + + op.patch_op = patch_op; + op.portmask = portmask; + op.pagemmd = pagemmd; + op.addr = addr; + op.msb = msb; + op.lsb = lsb; + op.data = data; + op.compare_op = RTK_PATCH_CMP_W; + + return pPhy_patchDb->fPatch_op(unit, port, portOffset, &op, patch_mode); +} + +static int32 _phy_patch_process(uint32 unit, rtk_port_t port, uint8 portOffset, rtk_hwpatch_t *pPatch, int32 size, uint8 patch_mode) +{ + int32 i = 0; + int32 ret = 0; + int32 chk_ret = RT_ERR_OK; + int32 n; + rtk_hwpatch_t *patch = pPatch; + rt_phy_patch_db_t *pPatchDb = NULL; + + PHYPATCH_DB_GET(unit, port, pPatchDb); + + if (size <= 0) + { + return RT_ERR_OK; + } + n = size / sizeof(rtk_hwpatch_t); + + for (i = 0; i < n; i++) + { + ret = pPatchDb->fPatch_op(unit, port, portOffset, &patch[i], patch_mode); + if ((ret != RT_ERR_ABORT) && (ret != RT_ERR_OK)) + { + if ((ret == RT_ERR_CHECK_FAILED) && (patch_mode == PHY_PATCH_MODE_CMP)) + { + osal_printf("PATCH CHECK: Failed entry:%u|%u|0x%X|0x%X|%u|%u|0x%X\n", + i + 1, patch[i].patch_op, patch[i].pagemmd, patch[i].addr, patch[i].msb, patch[i].lsb, patch[i].data); + chk_ret = RT_ERR_CHECK_FAILED; + continue; + } + else + { + RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u %s failed! %u[%u][0x%X][0x%X][0x%X] ret=0x%X\n", unit, port, __FUNCTION__, + i+1, patch[i].patch_op, patch[i].pagemmd, patch[i].addr, patch[i].data, ret); + return ret; + } + } + + } + return (chk_ret == RT_ERR_CHECK_FAILED) ? chk_ret : RT_ERR_OK; +} + +/* Function Name: + * phy_patch + * Description: + * apply initial patch data to PHY + * Input: + * unit - unit id + * port - port id + * portOffset - the index offset of port based the base port in the PHY chip + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_CHECK_FAILED + * RT_ERR_NOT_SUPPORTED + * Note: + * None + */ +int32 phy_patch(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_mode) +{ + int32 ret = RT_ERR_OK; + int32 chk_ret = RT_ERR_OK; + uint32 i = 0; + uint8 patch_type = 0; + rt_phy_patch_db_t *pPatchDb = NULL; + rtk_hwpatch_seq_t *table = NULL; + + PHYPATCH_DB_GET(unit, port, pPatchDb); + + if ((pPatchDb == NULL) || (pPatchDb->fPatch_op == NULL) || (pPatchDb->fPatch_flow == NULL)) + { + RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u phy_patch, db is NULL\n", unit, port); + return RT_ERR_DRIVER_NOT_SUPPORTED; + } + + if (patch_mode == PHY_PATCH_MODE_CMP) + { + table = pPatchDb->cmp_table; + } + else + { + table = pPatchDb->seq_table; + } + RT_LOG(LOG_INFO, (MOD_HAL | MOD_PHY), "phy_patch: U%u P%u portOffset:%u patch_mode:%u\n", unit, port, portOffset, patch_mode); + + for (i = 0; i < RTK_PATCH_SEQ_MAX; i++) + { + patch_type = table[i].patch_type; + RT_LOG(LOG_INFO, (MOD_HAL | MOD_PHY), "phy_patch: table[%u] patch_type:%u\n", i, patch_type); + + if (RTK_PATCH_TYPE_IS_DATA(patch_type)) + { + ret = _phy_patch_process(unit, port, portOffset, table[i].patch.data.conf, table[i].patch.data.size, patch_mode); + + if (ret == RT_ERR_CHECK_FAILED) + chk_ret = ret; + else if (ret != RT_ERR_OK) + { + RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u patch_mode:%u id:%u patch-%u failed. ret:0x%X\n", unit, port, patch_mode, i, patch_type, ret); + return ret; + } + } + else if (RTK_PATCH_TYPE_IS_FLOW(patch_type)) + { + RT_ERR_CHK_EHDL(pPatchDb->fPatch_flow(unit, port, portOffset, table[i].patch.flow_id, patch_mode), + ret, RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u patch_mode:%u id:%u patch-%u failed. ret:0x%X\n", unit, port, patch_mode, i, patch_type, ret);); + } + else + { + break; + } + } + + return (chk_ret == RT_ERR_CHECK_FAILED) ? chk_ret : RT_ERR_OK; +} + + + + diff --git a/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/phy_patch.h b/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/phy_patch.h new file mode 100644 index 00000000000..c2b7b1279c7 --- /dev/null +++ b/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/phy_patch.h @@ -0,0 +1,174 @@ +/* + * SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved. + */ + +#ifndef __HAL_PHY_PATCH_H__ +#define __HAL_PHY_PATCH_H__ + +/* + * Include Files + */ +#if defined(RTK_PHYDRV_IN_LINUX) + #include "rtk_phylib_def.h" +#else + #include + #include +#endif + +/* + * Symbol Definition + */ +#define PHYPATCH_PHYCTRL_IN_HALCTRL 0 /* 3.6.x: 1 ,4.0.x: 1, 4.1.x+: 0 */ +#define PHYPATCH_FMAILY_IN_HWP 0 /* 3.6.x: 1 ,4.0.x: 0, 4.1.x+: 0 */ +#define PHY_PATCH_MODE_BCAST_DEFAULT PHY_PATCH_MODE_BCAST /* 3.6.x: PHY_PATCH_MODE_BCAST_BUS ,4.0.x+: PHY_PATCH_MODE_BCAST */ + +#define PHY_PATCH_MODE_NORMAL 0 +#define PHY_PATCH_MODE_CMP 1 +#define PHY_PATCH_MODE_BCAST 2 +#define PHY_PATCH_MODE_BCAST_BUS 3 + +#define RTK_PATCH_CMP_W 0 /* write */ +#define RTK_PATCH_CMP_WC 1 /* compare */ +#define RTK_PATCH_CMP_SWC 2 /* sram compare */ +#define RTK_PATCH_CMP_WS 3 /* skip */ + +#define RTK_PATCH_OP_SECTION_SIZE 50 +#define RTK_PATCH_OP_TO_CMP(_op, _cmp) (_op + (RTK_PATCH_OP_SECTION_SIZE * _cmp)) +/* 0~49 normal op */ +#define RTK_PATCH_OP_PHY 0 +#define RTK_PATCH_OP_PHYOCP 1 +#define RTK_PATCH_OP_TOP 2 +#define RTK_PATCH_OP_TOPOCP 3 +#define RTK_PATCH_OP_PSDS0 4 +#define RTK_PATCH_OP_PSDS1 5 +#define RTK_PATCH_OP_MSDS 6 +#define RTK_PATCH_OP_MAC 7 + +/* 50~99 normal op for compare */ +#define RTK_PATCH_OP_CMP_PHY RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_PHY , RTK_PATCH_CMP_WC) +#define RTK_PATCH_OP_CMP_PHYOCP RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_PHYOCP , RTK_PATCH_CMP_WC) +#define RTK_PATCH_OP_CMP_TOP RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_TOP , RTK_PATCH_CMP_WC) +#define RTK_PATCH_OP_CMP_TOPOCP RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_TOPOCP , RTK_PATCH_CMP_WC) +#define RTK_PATCH_OP_CMP_PSDS0 RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_PSDS0 , RTK_PATCH_CMP_WC) +#define RTK_PATCH_OP_CMP_PSDS1 RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_PSDS1 , RTK_PATCH_CMP_WC) +#define RTK_PATCH_OP_CMP_MSDS RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_MSDS , RTK_PATCH_CMP_WC) +#define RTK_PATCH_OP_CMP_MAC RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_MAC , RTK_PATCH_CMP_WC) + +/* 100~149 normal op for sram compare */ +#define RTK_PATCH_OP_CMP_SRAM_PHY RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_PHY , RTK_PATCH_CMP_SWC) +#define RTK_PATCH_OP_CMP_SRAM_PHYOCP RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_PHYOCP , RTK_PATCH_CMP_SWC) +#define RTK_PATCH_OP_CMP_SRAM_TOP RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_TOP , RTK_PATCH_CMP_SWC) +#define RTK_PATCH_OP_CMP_SRAM_TOPOCP RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_TOPOCP , RTK_PATCH_CMP_SWC) +#define RTK_PATCH_OP_CMP_SRAM_PSDS0 RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_PSDS0 , RTK_PATCH_CMP_SWC) +#define RTK_PATCH_OP_CMP_SRAM_PSDS1 RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_PSDS1 , RTK_PATCH_CMP_SWC) +#define RTK_PATCH_OP_CMP_SRAM_MSDS RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_MSDS , RTK_PATCH_CMP_SWC) +#define RTK_PATCH_OP_CMP_SRAM_MAC RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_MAC , RTK_PATCH_CMP_SWC) + +/* 200~255 control op */ +#define RTK_PATCH_OP_DELAY_MS 200 +#define RTK_PATCH_OP_SKIP 255 + + +/* + patch type PHY_PATCH_TYPE_NONE => empty + patch type: PHY_PATCH_TYPE_TOP ~ (PHY_PATCH_TYPE_END-1) => data array + patch type: PHY_PATCH_TYPE_END ~ (PHY_PATCH_TYPE_END + RTK_PATCH_TYPE_FLOW_MAX) => flow +*/ +#define RTK_PATCH_TYPE_IS_DATA(_patch_type) (_patch_type > PHY_PATCH_TYPE_NONE && _patch_type < PHY_PATCH_TYPE_END) +#define RTK_PATCH_TYPE_IS_FLOW(_patch_type) (_patch_type >= PHY_PATCH_TYPE_END && _patch_type <= (PHY_PATCH_TYPE_END + RTK_PATCH_TYPE_FLOWID_MAX)) + + +/* + * Macro Definition + */ +#if PHYPATCH_PHYCTRL_IN_HALCTRL + #define PHYPATCH_DB_GET(_unit, _port, _pPatchDb) \ + do {\ + hal_control_t *pHalCtrl = NULL;\ + if ((pHalCtrl = hal_ctrlInfo_get(_unit)) == NULL)\ + return RT_ERR_FAILED;\ + _pPatchDb = (pHalCtrl->pPhy_ctrl[_port]->pPhy_patchDb);\ + } while(0) +#else + #if defined(RTK_PHYDRV_IN_LINUX) + #else + #include + #include + #endif + #define PHYPATCH_DB_GET(_unit, _port, _pPatchDb) \ + do {\ + rt_phyctrl_t *pPhyCtrl = NULL;\ + if ((pPhyCtrl = phy_phyctrl_get(_unit, _port)) == NULL)\ + return RT_ERR_FAILED;\ + _pPatchDb = (pPhyCtrl->pPhy_patchDb);\ + } while(0) +#endif + +#if PHYPATCH_FMAILY_IN_HWP + #define PHYPATCH_IS_RTKSDS(_unit) (HWP_9300_FAMILY_ID(_unit) || HWP_9310_FAMILY_ID(_unit)) +#else + #define PHYPATCH_IS_RTKSDS(_unit) (RTK_9300_FAMILY_ID(_unit) || RTK_9310_FAMILY_ID(_unit) || RTK_9311B_FAMILY_ID(_unit) || RTK_9330_FAMILY_ID(_unit)) +#endif + +#define PHYPATCH_TABLE_ASSIGN(_pPatchDb, _table, _idx, _patch_type, _para) \ + do {\ + if (RTK_PATCH_TYPE_IS_DATA(_patch_type)) {\ + _pPatchDb->_table[_idx].patch_type = _patch_type;\ + _pPatchDb->_table[_idx].patch.data.conf = _para;\ + _pPatchDb->_table[_idx].patch.data.size = sizeof(_para);\ + }\ + else if (RTK_PATCH_TYPE_IS_FLOW(_patch_type)) {\ + _pPatchDb->_table[_idx].patch_type = _patch_type;\ + _pPatchDb->_table[_idx].patch.flow_id = _patch_type;\ + }\ + else {\ + _pPatchDb->_table[_idx].patch_type = PHY_PATCH_TYPE_NONE;\ + }\ + } while(0) +#define PHYPATCH_SEQ_TABLE_ASSIGN(_pPatchDb, _idx, _patch_type, _para) PHYPATCH_TABLE_ASSIGN(_pPatchDb, seq_table, _idx, _patch_type, _para) +#define PHYPATCH_CMP_TABLE_ASSIGN(_pPatchDb, _idx, _patch_type, _para) PHYPATCH_TABLE_ASSIGN(_pPatchDb, cmp_table, _idx, _patch_type, _para) + +#define PHYPATCH_COMPARE(_mmdpage, _reg, _msb, _lsb, _exp, _real, _mask) \ + do {\ + uint32 _rData = REG32_FIELD_GET(_real, _lsb, _mask);\ + if (_exp != _rData) {\ + osal_printf("PATCH CHECK: %u(0x%X).%u(0x%X)[%u:%u] = 0x%X (!= 0x%X)\n", _mmdpage, _mmdpage, _reg, _reg, _msb, _lsb, _rData, _exp);\ + return RT_ERR_CHECK_FAILED;\ + }\ + } while (0) + +/* + * Function Declaration + */ + +extern uint8 phy_patch_op_translate(uint8 patch_mode, uint8 patch_op, uint8 compare_op); +extern int32 phy_patch_op(rt_phy_patch_db_t *pPhy_patchDb, uint32 unit, rtk_port_t port, uint8 portOffset, + uint8 patch_op, uint16 portmask, uint16 pagemmd, uint16 addr, uint8 msb, uint8 lsb, uint16 data, + uint8 patch_mode); + + +/* Function Name: + * phy_patch + * Description: + * apply initial patch data to PHY + * Input: + * unit - unit id + * port - port id + * portOffset - the index offset of port based the base port in the PHY chip + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_CHECK_FAILED + * RT_ERR_NOT_SUPPORTED + * Note: + * None + */ +extern int32 phy_patch(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_mode); + + + +#endif /* __HAL_PHY_PATCH_H__ */ diff --git a/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/phy_rtl826xb_patch.c b/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/phy_rtl826xb_patch.c new file mode 100644 index 00000000000..90a792a17b2 --- /dev/null +++ b/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/phy_rtl826xb_patch.c @@ -0,0 +1,1031 @@ +/* + * SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved. + */ + +/* + * Include Files + */ +#if defined(RTK_PHYDRV_IN_LINUX) + #include "phy_rtl826xb_patch.h" + #include "construct/conf_rtl8264b.c" + #include "construct/conf_rtl8261n_c.c" +#else + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #if defined(CONFIG_SDK_RTL826XB) + #include + #include + #include + #endif +#endif +/* + * Symbol Definition + */ +#define PHY_PATCH_WAIT_TIMEOUT 10000000 + +#define PHY_PATCH_LOG LOG_INFO + +/* + * Data Declaration + */ + +/* + * Macro Declaration + */ + +/* + * Function Declaration + */ +static uint16 _phy_rtl826xb_mmd_convert(uint16 page, uint16 addr) +{ + uint16 reg = 0; + if (addr < 16) + { + reg = 0xA400 + (page * 2); + } + else if (addr < 24) + { + reg = (16*page) + ((addr - 16) * 2); + } + else + { + reg = 0xA430 + ((addr - 24) * 2); + } + return reg; +} + +int32 +_phy_rtl826xb_patch_wait(uint32 unit, rtk_port_t port, uint32 mmdAddr, uint32 mmdReg, uint32 data, uint32 mask, uint8 patch_mode) +{ + int32 ret = 0; + uint32 rData = 0; + uint32 cnt = 0; + WAIT_COMPLETE_VAR() + + rtk_port_t p = 0; + uint8 smiBus = HWP_PORT_SMI(unit, port); + uint32 phyChip = HWP_PHY_MODEL_BY_PORT(unit, port); + uint8 bcast_phyad = HWP_PHY_ADDR(unit, port);; + + + if (patch_mode == PHY_PATCH_MODE_BCAST_BUS) + { + if ((ret = phy_826xb_ctrl_set(unit, port, RTK_PHY_CTRL_MIIM_BCAST, 0)) != RT_ERR_OK) + { + RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u 826XB patch wait disable broadcast failed! 0x%X\n", unit, p, ret); + return ret; + } + + HWP_PORT_TRAVS_EXCEPT_CPU(unit, p) + { + if ((HWP_PORT_SMI(unit, p) == smiBus) && (HWP_PHY_MODEL_BY_PORT(unit, p) == phyChip)) + { + WAIT_COMPLETE(PHY_PATCH_WAIT_TIMEOUT) + { + if ((ret = phy_common_general_reg_mmd_get(unit, p, mmdAddr, mmdReg, &rData)) != RT_ERR_OK) + { + return ret; + } + ++cnt; + + if ((rData & mask) == data) + break; + + //osal_time_udelay(10); + } + + if (WAIT_COMPLETE_IS_TIMEOUT()) + { + RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u 826XB patch wait[%u,0x%X,0x%X,0x%X]:0x%X cnt:%u\n", unit, p, mmdAddr, mmdReg, data, mask, rData, cnt); + return RT_ERR_TIMEOUT; + } + } + } + + osal_time_mdelay(1); + //for port in same SMI bus, set mdio broadcast ENABLE + HWP_PORT_TRAVS_EXCEPT_CPU(unit, p) + { + if ((HWP_PORT_SMI(unit, p) == smiBus) && (HWP_PHY_MODEL_BY_PORT(unit, p) == phyChip)) + { + if ((ret = phy_826xb_ctrl_set(unit, p, RTK_PHY_CTRL_MIIM_BCAST_PHYAD, (uint32)bcast_phyad)) != RT_ERR_OK) + { + RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u 826XB patch wait set broadcast PHYAD failed! 0x%X\n", unit, p, ret); + return ret; + } + + if ((ret = phy_826xb_ctrl_set(unit, p, RTK_PHY_CTRL_MIIM_BCAST, 1)) != RT_ERR_OK) + { + RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u 826XB patch wait enable broadcast failed! 0x%X\n", unit, p, ret); + return ret; + } + } + } + } + else if (patch_mode == PHY_PATCH_MODE_BCAST) + { + if ((ret = phy_826xb_ctrl_set(unit, port, RTK_PHY_CTRL_MIIM_BCAST, 0)) != RT_ERR_OK) + { + RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u 826x patch wait disable broadcast failed! 0x%X\n", unit, p, ret); + return ret; + } + + HWP_PORT_TRAVS_EXCEPT_CPU(unit, p) + { + if (HWP_PHY_BASE_MACID(unit, p) == HWP_PHY_BASE_MACID(unit, port)) + { + WAIT_COMPLETE(PHY_PATCH_WAIT_TIMEOUT) + { + if ((ret = phy_common_general_reg_mmd_get(unit, p, mmdAddr, mmdReg, &rData)) != RT_ERR_OK) + { + return ret; + } + ++cnt; + + if ((rData & mask) == data) + break; + //osal_time_udelay(10); + } + + if (WAIT_COMPLETE_IS_TIMEOUT()) + { + RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u 826x patch wait[%u,0x%X,0x%X,0x%X]:0x%X cnt:%u\n", unit, p, mmdAddr, mmdReg, data, mask, rData, cnt); + return RT_ERR_TIMEOUT; + } + } + } + + osal_time_mdelay(1); + //for port in same PHY, set mdio broadcast ENABLE + HWP_PORT_TRAVS_EXCEPT_CPU(unit, p) + { + if (HWP_PHY_BASE_MACID(unit, p) == HWP_PHY_BASE_MACID(unit, port)) + { + if ((ret = phy_826xb_ctrl_set(unit, p, RTK_PHY_CTRL_MIIM_BCAST_PHYAD, (uint32)bcast_phyad)) != RT_ERR_OK) + { + RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u 826XB patch wait set broadcast PHYAD failed! 0x%X\n", unit, p, ret); + return ret; + } + + if ((ret = phy_826xb_ctrl_set(unit, p, RTK_PHY_CTRL_MIIM_BCAST, 1)) != RT_ERR_OK) + { + RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u 826XB patch wait enable broadcast failed! 0x%X\n", unit, p, ret); + return ret; + } + } + } + } + else + { + WAIT_COMPLETE(PHY_PATCH_WAIT_TIMEOUT) + { + if ((ret = phy_common_general_reg_mmd_get(unit, port, mmdAddr, mmdReg, &rData)) != RT_ERR_OK) + return ret; + + ++cnt; + if ((rData & mask) == data) + break; + + osal_time_mdelay(1); + } + + if (WAIT_COMPLETE_IS_TIMEOUT()) + { + RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u 826XB patch wait[%u,0x%X,0x%X,0x%X]:0x%X cnt:%u\n", unit, port, mmdAddr, mmdReg, data, mask, rData, cnt); + return RT_ERR_TIMEOUT; + } + } + + return RT_ERR_OK; +} + +int32 +_phy_rtl826xb_patch_wait_not_equal(uint32 unit, rtk_port_t port, uint32 mmdAddr, uint32 mmdReg, uint32 data, uint32 mask, uint8 patch_mode) +{ + int32 ret = 0; + uint32 rData = 0; + uint32 cnt = 0; + WAIT_COMPLETE_VAR() + + rtk_port_t p = 0; + uint8 smiBus = HWP_PORT_SMI(unit, port); + uint32 phyChip = HWP_PHY_MODEL_BY_PORT(unit, port); + uint8 bcast_phyad = HWP_PHY_ADDR(unit, port); + + if (patch_mode == PHY_PATCH_MODE_BCAST_BUS) + { + if ((ret = phy_826xb_ctrl_set(unit, port, RTK_PHY_CTRL_MIIM_BCAST, 0)) != RT_ERR_OK) + { + RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u 826XB patch wait disable broadcast failed! 0x%X\n", unit, p, ret); + return ret; + } + + HWP_PORT_TRAVS_EXCEPT_CPU(unit, p) + { + if ((HWP_PORT_SMI(unit, p) == smiBus) && (HWP_PHY_MODEL_BY_PORT(unit, p) == phyChip)) + { + WAIT_COMPLETE(PHY_PATCH_WAIT_TIMEOUT) + { + if ((ret = phy_common_general_reg_mmd_get(unit, p, mmdAddr, mmdReg, &rData)) != RT_ERR_OK) + { + return ret; + } + ++cnt; + + if ((rData & mask) != data) + break; + + //osal_time_udelay(10); + } + if (WAIT_COMPLETE_IS_TIMEOUT()) + { + RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u 826XB patch wait[%u,0x%X,0x%X,0x%X]:0x%X cnt:%u\n", unit, p, mmdAddr, mmdReg, data, mask, rData, cnt); + return RT_ERR_TIMEOUT; + } + } + } + + osal_time_mdelay(1); + //for port in same SMI bus, set mdio broadcast ENABLE + HWP_PORT_TRAVS_EXCEPT_CPU(unit, p) + { + if ((HWP_PORT_SMI(unit, p) == smiBus) && (HWP_PHY_MODEL_BY_PORT(unit, p) == phyChip)) + { + if ((ret = phy_826xb_ctrl_set(unit, p, RTK_PHY_CTRL_MIIM_BCAST_PHYAD, (uint32)bcast_phyad)) != RT_ERR_OK) + { + RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u 826XB patch wait set broadcast PHYAD failed! 0x%X\n", unit, p, ret); + return ret; + } + + if ((ret = phy_826xb_ctrl_set(unit, p, RTK_PHY_CTRL_MIIM_BCAST, 1)) != RT_ERR_OK) + { + RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u 826XB patch wait enable broadcast failed! 0x%X\n", unit, p, ret); + return ret; + } + } + } + } + else if (patch_mode == PHY_PATCH_MODE_BCAST) + { + if ((ret = phy_826xb_ctrl_set(unit, port, RTK_PHY_CTRL_MIIM_BCAST, 0)) != RT_ERR_OK) + { + RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u 826x patch wait disable broadcast failed! 0x%X\n", unit, p, ret); + return ret; + } + + HWP_PORT_TRAVS_EXCEPT_CPU(unit, p) + { + if (HWP_PHY_BASE_MACID(unit, p) == HWP_PHY_BASE_MACID(unit, port)) + { + WAIT_COMPLETE(PHY_PATCH_WAIT_TIMEOUT) + { + if ((ret = phy_common_general_reg_mmd_get(unit, p, mmdAddr, mmdReg, &rData)) != RT_ERR_OK) + { + return ret; + } + ++cnt; + + if (((rData & mask) != data)) + break; + + //osal_time_udelay(10); + } + + if (WAIT_COMPLETE_IS_TIMEOUT()) + { + RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u 826XB patch wait[%u,0x%X,0x%X,0x%X]:0x%X cnt:%u\n", unit, p, mmdAddr, mmdReg, data, mask, rData, cnt); + return RT_ERR_TIMEOUT; + } + } + } + + osal_time_mdelay(1); + //for port in same PHY, set mdio broadcast ENABLE + HWP_PORT_TRAVS_EXCEPT_CPU(unit, p) + { + if (HWP_PHY_BASE_MACID(unit, p) == HWP_PHY_BASE_MACID(unit, port)) + { + if ((ret = phy_826xb_ctrl_set(unit, p, RTK_PHY_CTRL_MIIM_BCAST_PHYAD, (uint32)bcast_phyad)) != RT_ERR_OK) + { + RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u 826XB patch wait set broadcast PHYAD failed! 0x%X\n", unit, p, ret); + return ret; + } + + if ((ret = phy_826xb_ctrl_set(unit, p, RTK_PHY_CTRL_MIIM_BCAST, 1)) != RT_ERR_OK) + { + RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u 826XB patch wait enable broadcast failed! 0x%X\n", unit, p, ret); + return ret; + } + } + } + } + else + { + WAIT_COMPLETE(PHY_PATCH_WAIT_TIMEOUT) + { + if ((ret = phy_common_general_reg_mmd_get(unit, port, mmdAddr, mmdReg, &rData)) != RT_ERR_OK) + return ret; + + ++cnt; + if ((rData & mask) != data) + break; + + osal_time_mdelay(1); + } + if (WAIT_COMPLETE_IS_TIMEOUT()) + { + RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u 826xb patch wait[%u,0x%X,0x%X,0x%X]:0x%X cnt:%u\n", unit, port, mmdAddr, mmdReg, data, mask, rData, cnt); + return RT_ERR_TIMEOUT; + } + + } + + return RT_ERR_OK; +} + +int32 +_phy_rtl826xb_patch_top_get(uint32 unit, rtk_port_t port, uint32 topPage, uint32 topReg, uint32 *pData) +{ + int32 ret = 0; + uint32 rData = 0; + uint32 topAddr = (topPage * 8) + (topReg - 16); + + if ((ret = phy_common_general_reg_mmd_get(unit, port, PHY_MMD_VEND1, topAddr, &rData)) != RT_ERR_OK) + return ret; + *pData = rData; + return RT_ERR_OK; +} + +int32 +_phy_rtl826xb_patch_top_set(uint32 unit, rtk_port_t port, uint32 topPage, uint32 topReg, uint32 wData) +{ + int32 ret = 0; + uint32 topAddr = (topPage * 8) + (topReg - 16); + if ((ret = phy_common_general_reg_mmd_set(unit, port, PHY_MMD_VEND1, topAddr, wData)) != RT_ERR_OK) + return ret; + return RT_ERR_OK; +} + +int32 +_phy_rtl826xb_patch_sds_get(uint32 unit, rtk_port_t port, uint32 sdsPage, uint32 sdsReg, uint32 *pData) +{ + int32 ret = 0; + uint32 rData = 0; + uint32 sdsAddr = 0x8000 + (sdsReg << 6) + sdsPage; + + if ((ret = _phy_rtl826xb_patch_top_set(unit, port, 40, 19, sdsAddr)) != RT_ERR_OK) + return ret; + if ((ret = _phy_rtl826xb_patch_top_get(unit, port, 40, 18, &rData)) != RT_ERR_OK) + return ret; + *pData = rData; + return _phy_rtl826xb_patch_wait(unit, port, PHY_MMD_VEND1, 0x143, 0, BIT_15, PHY_PATCH_MODE_NORMAL); +} + +int32 +_phy_rtl826xb_patch_sds_set(uint32 unit, rtk_port_t port, uint32 sdsPage, uint32 sdsReg, uint32 wData, uint8 patch_mode) +{ + int32 ret = 0; + uint32 sdsAddr = 0x8800 + (sdsReg << 6) + sdsPage; + + if ((ret = _phy_rtl826xb_patch_top_set(unit, port, 40, 17, wData)) != RT_ERR_OK) + return ret; + if ((ret = _phy_rtl826xb_patch_top_set(unit, port, 40, 19, sdsAddr)) != RT_ERR_OK) + return ret; + return _phy_rtl826xb_patch_wait(unit, port, PHY_MMD_VEND1, 0x143, 0, BIT_15, patch_mode); +} + +static int32 _phy_rtl826xb_flow_r1(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_mode) +{ + int32 ret = RT_ERR_OK; + rt_phy_patch_db_t *pPatchDb = NULL; + + PHYPATCH_DB_GET(unit, port, pPatchDb); + + //PHYReg_bit w $PHYID 0xb82 16 4 4 0x1 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xb82, 16, 4, 4, 0x1, patch_mode), ret); + //PHYReg_bit w $PHYID 0xb82 16 4 4 0x1 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xb82, 16, 4, 4, 0x1, patch_mode), ret); + + //set patch_rdy [PHYReg_bit r $PHYID 0xb80 16 6 6] ; Wait for patch ready = 1 + RT_ERR_CHK(_phy_rtl826xb_patch_wait(unit, port, 31, _phy_rtl826xb_mmd_convert(0xb80, 16), BIT_6, BIT_6, patch_mode), ret); + + //PHYReg w $PHYID 0xa43 27 $0x8023 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa43, 27, 15, 0, 0x8023, patch_mode), ret); + //PHYReg w $PHYID 0xa43 28 $0x3802 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa43, 28, 15, 0, 0x3802, patch_mode), ret); + //PHYReg w $PHYID 0xa43 27 0xB82E + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa43, 27, 15, 0, 0xB82E, patch_mode), ret); + //PHYReg w $PHYID 0xa43 28 0x1 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa43, 28, 15, 0, 0x1, patch_mode), ret); + + return RT_ERR_OK; +} + +static int32 _phy_rtl826xb_flow_r12(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_mode) +{ + int32 ret = RT_ERR_OK; + rt_phy_patch_db_t *pPatchDb = NULL; + + PHYPATCH_DB_GET(unit, port, pPatchDb); + + //PHYReg_bit w $PHYID 0xb82 16 4 4 0x1 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xb82, 16, 4, 4, 0x1, patch_mode), ret); + //PHYReg_bit w $PHYID 0xb82 16 4 4 0x1 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xb82, 16, 4, 4, 0x1, patch_mode), ret); + + //set patch_rdy [PHYReg_bit r $PHYID 0xb80 16 6 6] ; Wait for patch ready = 1 + RT_ERR_CHK(_phy_rtl826xb_patch_wait(unit, port, 31, _phy_rtl826xb_mmd_convert(0xb80, 16), BIT_6, BIT_6, patch_mode), ret); + + //PHYReg w $PHYID 0xa43 27 $0x8023 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa43, 27, 15, 0, 0x8023, patch_mode), ret); + //PHYReg w $PHYID 0xa43 28 $0x3800 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa43, 28, 15, 0, 0x3800, patch_mode), ret); + //PHYReg w $PHYID 0xa43 27 0xB82E + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa43, 27, 15, 0, 0xB82E, patch_mode), ret); + //PHYReg w $PHYID 0xa43 28 0x1 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa43, 28, 15, 0, 0x1, patch_mode), ret); + + return RT_ERR_OK; +} + + +static int32 _phy_rtl826xb_flow_r2(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_mode) +{ + int32 ret = RT_ERR_OK; + rt_phy_patch_db_t *pPatchDb = NULL; + + PHYPATCH_DB_GET(unit, port, pPatchDb); + + //PHYReg w $PHYID 0xa43 27 0x0000 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa43, 27, 15, 0, 0x0000, patch_mode), ret); + //PHYReg w $PHYID 0xa43 28 0x0000 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa43, 28, 15, 0, 0x0000, patch_mode), ret); + //PHYReg_bit w $PHYID 0xB82 23 0 0 0x0 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xB82, 23, 0, 0, 0x0, patch_mode), ret); + //PHYReg w $PHYID 0xa43 27 $0x8023 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa43, 27, 15, 0, 0x8023, patch_mode), ret); + //PHYReg w $PHYID 0xa43 28 0x0000 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa43, 28, 15, 0, 0x0000, patch_mode), ret); + + //PHYReg_bit w $PHYID 0xb82 16 4 4 0x0 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xb82, 16, 4, 4, 0x0, patch_mode), ret); + //set patch_rdy [PHYReg_bit r $PHYID 0xb80 16 6 6] ; Wait for patch ready != 1 + RT_ERR_CHK( _phy_rtl826xb_patch_wait_not_equal(unit, port, 31, _phy_rtl826xb_mmd_convert(0xb80, 16), BIT_6, BIT_6, patch_mode), ret); + + return RT_ERR_OK; +} + +static int32 _phy_rtl826xb_flow_l1(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_mode) +{ + int32 ret = RT_ERR_OK; + rt_phy_patch_db_t *pPatchDb = NULL; + + PHYPATCH_DB_GET(unit, port, pPatchDb); + + //PHYReg_bit w $PHYID 0xa4a 16 10 10 0x1 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa4a, 16, 10, 10, 0x1, patch_mode), ret); + //PHYReg_bit w $PHYID 0xa4a 16 10 10 0x1 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa4a, 16, 10, 10, 0x1, patch_mode), ret); + + //set pcs_state [PHYReg_bit r $PHYID 0xa60 16 7 0] ; Wait for pcs state = 1 + RT_ERR_CHK( _phy_rtl826xb_patch_wait(unit, port, 31, _phy_rtl826xb_mmd_convert(0xa60, 16), 0x1, 0xFF, patch_mode), ret); + + return RT_ERR_OK; +} + +static int32 _phy_rtl826xb_flow_l2(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_mode) +{ + int32 ret = RT_ERR_OK; + rt_phy_patch_db_t *pPatchDb = NULL; + + PHYPATCH_DB_GET(unit, port, pPatchDb); + + //PHYReg_bit w $PHYID 0xa4a 16 10 10 0x0 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa4a, 16, 10, 10, 0x0, patch_mode), ret); + + //set pcs_state [PHYReg_bit r $PHYID 0xa60 16 7 0] ; Wait for pcs state != 1 + RT_ERR_CHK( _phy_rtl826xb_patch_wait_not_equal(unit, port, 31, _phy_rtl826xb_mmd_convert(0xa60, 16), 0x1, 0xFF, patch_mode), ret); + + return RT_ERR_OK; +} + +static int32 _phy_rtl826xb_flow_pi(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_mode) +{ + int32 ret = RT_ERR_OK; + rt_phy_patch_db_t *pPatchDb = NULL; + uint32 rData = 0, cnt = 0; + + PHYPATCH_DB_GET(unit, port, pPatchDb); + + _phy_rtl826xb_flow_l1(unit, port, portOffset, patch_mode); + + // PP_PHYReg_bit w $PHYID 0xbf86 9 9 0x1; #SS_EN_XG = 1 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHYOCP, 0xFF, 31, 0xbf86, 9, 9, 0x1, patch_mode), ret); + // PP_PHYReg_bit w $PHYID 0xbf86 8 8 0x0; + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHYOCP, 0xFF, 31, 0xbf86, 8, 8, 0x0, patch_mode), ret); + // PP_PHYReg_bit w $PHYID 0xbf86 7 7 0x1; + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHYOCP, 0xFF, 31, 0xbf86, 7, 7, 0x1, patch_mode), ret); + // PP_PHYReg_bit w $PHYID 0xbf86 6 6 0x1; + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHYOCP, 0xFF, 31, 0xbf86, 6, 6, 0x1, patch_mode), ret); + // PP_PHYReg_bit w $PHYID 0xbf86 5 5 0x1; + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHYOCP, 0xFF, 31, 0xbf86, 5, 5, 0x1, patch_mode), ret); + // PP_PHYReg_bit w $PHYID 0xbf86 4 4 0x1; + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHYOCP, 0xFF, 31, 0xbf86, 4, 4, 0x1, patch_mode), ret); + // PP_PHYReg_bit w $PHYID 0xbf86 6 6 0x0; + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHYOCP, 0xFF, 31, 0xbf86, 6, 6, 0x0, patch_mode), ret); + // PP_PHYReg_bit w $PHYID 0xbf86 9 9 0x0; + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHYOCP, 0xFF, 31, 0xbf86, 9, 9, 0x0, patch_mode), ret); + // PP_PHYReg_bit w $PHYID 0xbf86 7 7 0x0; + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHYOCP, 0xFF, 31, 0xbf86, 7, 7, 0x0, patch_mode), ret); + + //PP_PHYReg_bit r $PHYID 0xbc62 12 8 + if ((ret = phy_common_general_reg_mmd_get(unit, port, PHY_MMD_VEND2, 0xbc62, &rData)) != RT_ERR_OK) + return ret; + rData = REG32_FIELD_GET(rData, 8, 0x1F00); + for (cnt = 0; cnt <= rData; cnt++) + { + //PP_PHYReg_bit w $PHYID 0xbc62 12 8 $t + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHYOCP, 0xFF, 31, 0xbc62, 12, 8, cnt, patch_mode), ret); + } + + // PP_PHYReg_bit w $PHYID 0xbc02 2 2 0x1 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHYOCP, 0xFF, 31, 0xbc02, 2, 2, 0x1, patch_mode), ret); + // PP_PHYReg_bit w $PHYID 0xbc02 3 3 0x1 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHYOCP, 0xFF, 31, 0xbc02, 3, 3, 0x1, patch_mode), ret); + // PP_PHYReg_bit w $PHYID 0xbf86 6 6 0x1 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHYOCP, 0xFF, 31, 0xbf86, 6, 6, 0x1, patch_mode), ret); + // PP_PHYReg_bit w $PHYID 0xbf86 9 9 0x1 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHYOCP, 0xFF, 31, 0xbf86, 9, 9, 0x1, patch_mode), ret); + // PP_PHYReg_bit w $PHYID 0xbf86 7 7 0x1 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHYOCP, 0xFF, 31, 0xbf86, 7, 7, 0x1, patch_mode), ret); + // PP_PHYReg_bit w $PHYID 0xbc04 9 2 0xff + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHYOCP, 0xFF, 31, 0xbc04, 9, 2, 0xff, patch_mode), ret); + + _phy_rtl826xb_flow_l2(unit, port, portOffset, patch_mode); + return RT_ERR_OK; +} + +static int32 _phy_rtl826xb_flow_n01(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_mode) +{ + int32 ret = RT_ERR_OK; + rt_phy_patch_db_t *pPatchDb = NULL; + + PHYPATCH_DB_GET(unit, port, pPatchDb); + + //PHYReg_bit w $PHYID 0xa01 21 15 0 0x1 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa01, 21, 15, 0, 0x1, patch_mode), ret); + //PHYReg_bit w $PHYID 0xa01 19 15 0 0x0000 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa01, 19, 15, 0, 0x0000, patch_mode), ret); + //# PHYReg_bit w $PHYID 0xa01 17 15 0 0x0000 + //RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa01, 17, 15, 0, 0x0000, patch_mode), ret); + + return RT_ERR_OK; +} + +static int32 _phy_rtl826xb_flow_n02(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_mode) +{ + int32 ret = RT_ERR_OK; + rt_phy_patch_db_t *pPatchDb = NULL; + + PHYPATCH_DB_GET(unit, port, pPatchDb); + + //PHYReg_bit w $PHYID 0xa01 21 15 0 0x0 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa01, 21, 15, 0, 0x0, patch_mode), ret); + //PHYReg_bit w $PHYID 0xa01 19 15 0 0x0000 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa01, 19, 15, 0, 0x0000, patch_mode), ret); + //PHYReg_bit w $PHYID 0xa01 17 15 0 0x0000 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa01, 17, 15, 0, 0x0000, patch_mode), ret); + return RT_ERR_OK; +} + +static int32 _phy_rtl826xb_flow_n11(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_mode) +{ + int32 ret = RT_ERR_OK; + rt_phy_patch_db_t *pPatchDb = NULL; + + PHYPATCH_DB_GET(unit, port, pPatchDb); + + //PHYReg_bit w $PHYID 0xa01 21 15 0 0x1 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa01, 21, 15, 0, 0x1, patch_mode), ret); + //PHYReg_bit w $PHYID 0xa01 19 15 0 0x0010 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa01, 19, 15, 0, 0x0010, patch_mode), ret); + //# PHYReg_bit w $PHYID 0xa01 17 15 0 0x0000 + //RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa01, 17, 15, 0, 0x0000, patch_mode), ret); + + return RT_ERR_OK; +} + +static int32 _phy_rtl826xb_flow_n12(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_mode) +{ + int32 ret = RT_ERR_OK; + rt_phy_patch_db_t *pPatchDb = NULL; + + PHYPATCH_DB_GET(unit, port, pPatchDb); + + //PHYReg_bit w $PHYID 0xa01 21 15 0 0x0 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa01, 21, 15, 0, 0x0, patch_mode), ret); + //PHYReg_bit w $PHYID 0xa01 19 15 0 0x0010 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa01, 19, 15, 0, 0x0010, patch_mode), ret); + //PHYReg_bit w $PHYID 0xa01 17 15 0 0x0000 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa01, 17, 15, 0, 0x0000, patch_mode), ret); + + return RT_ERR_OK; +} + +static int32 _phy_rtl826xb_flow_n21(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_mode) +{ + int32 ret = RT_ERR_OK; + rt_phy_patch_db_t *pPatchDb = NULL; + + PHYPATCH_DB_GET(unit, port, pPatchDb); + + //PHYReg_bit w $PHYID 0xa01 21 15 0 0x1 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa01, 21, 15, 0, 0x1, patch_mode), ret); + //PHYReg_bit w $PHYID 0xa01 19 15 0 0x0020 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa01, 19, 15, 0, 0x0020, patch_mode), ret); + //# PHYReg_bit w $PHYID 0xa01 17 15 0 0x0000 + //RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa01, 17, 15, 0, 0x0000, patch_mode), ret); + + return RT_ERR_OK; +} + +static int32 _phy_rtl826xb_flow_n22(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_mode) +{ + int32 ret = RT_ERR_OK; + rt_phy_patch_db_t *pPatchDb = NULL; + + PHYPATCH_DB_GET(unit, port, pPatchDb); + + //PHYReg_bit w $PHYID 0xa01 21 15 0 0x0 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa01, 21, 15, 0, 0x0, patch_mode), ret); + //PHYReg_bit w $PHYID 0xa01 19 15 0 0x0020 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa01, 19, 15, 0, 0x0020, patch_mode), ret); + //PHYReg_bit w $PHYID 0xa01 17 15 0 0x0000 + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa01, 17, 15, 0, 0x0000, patch_mode), ret); + + return RT_ERR_OK; +} + +static int32 _phy_rtl826xb_flow_s(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_mode) +{ + int32 ret = RT_ERR_OK; + rt_phy_patch_db_t *pPatchDb = NULL; + + if (PHYPATCH_IS_RTKSDS(unit)) + { + PHYPATCH_DB_GET(unit, port, pPatchDb); + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PSDS0, 0xff, 0x07, 0x10, 15, 0, 0x80aa, patch_mode), ret); + RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PSDS0, 0xff, 0x06, 0x12, 15, 0, 0x5078, patch_mode), ret); + } + + return RT_ERR_OK; +} + +int32 phy_rtl826xb_patch_op(uint32 unit, rtk_port_t port, uint8 portOffset, rtk_hwpatch_t *pPatch_data, uint8 patch_mode) +{ + int32 ret = RT_ERR_OK; + uint32 rData = 0, wData = 0; + uint16 reg = 0; + uint8 patch_op = 0; + uint32 mask = 0; + + if ((pPatch_data->portmask & (1 << portOffset)) == 0) + { + return RT_ERR_ABORT; + } + mask = UINT32_BITS_MASK(pPatch_data->msb, pPatch_data->lsb); + patch_op = phy_patch_op_translate(patch_mode, pPatch_data->patch_op, pPatch_data->compare_op); + + #if 0 + osal_printf("[%s,%d]u%up%u, patch_mode:%u/patch_op:%u/compare_op:%u => op: %u\n", __FUNCTION__, __LINE__, unit, port, + patch_mode, pPatch_data->patch_op, pPatch_data->compare_op, + patch_op); + #endif + + switch (patch_op) + { + case RTK_PATCH_OP_PHY: + reg = _phy_rtl826xb_mmd_convert(pPatch_data->pagemmd, pPatch_data->addr); + if ((pPatch_data->msb != 15) || (pPatch_data->lsb != 0)) + { + RT_ERR_CHK(phy_common_general_reg_mmd_get(unit, port, 31, reg, &rData), ret); + } + wData = REG32_FIELD_SET(rData, pPatch_data->data, pPatch_data->lsb, mask); + RT_ERR_CHK(phy_common_general_reg_mmd_set(unit, port, 31, reg, wData), ret); + break; + case RTK_PATCH_OP_CMP_PHY: + reg = _phy_rtl826xb_mmd_convert(pPatch_data->pagemmd, pPatch_data->addr); + RT_ERR_CHK(phy_common_general_reg_mmd_get(unit, port, 31, reg, &rData), ret); + PHYPATCH_COMPARE(pPatch_data->pagemmd, pPatch_data->addr, pPatch_data->msb, pPatch_data->lsb, pPatch_data->data, rData, mask); + break; + case RTK_PATCH_OP_CMP_SRAM_PHY: + reg = _phy_rtl826xb_mmd_convert(pPatch_data->sram_p, pPatch_data->sram_rw); + RT_ERR_CHK(phy_common_general_reg_mmd_set(unit, port, 31, reg, pPatch_data->sram_a), ret); + reg = _phy_rtl826xb_mmd_convert(pPatch_data->sram_p, pPatch_data->sram_rr); + RT_ERR_CHK(phy_common_general_reg_mmd_get(unit, port, 31, reg, &rData), ret); + PHYPATCH_COMPARE(pPatch_data->pagemmd, pPatch_data->addr, pPatch_data->msb, pPatch_data->lsb, pPatch_data->data, rData, mask); + break; + + case RTK_PATCH_OP_PHYOCP: + if ((pPatch_data->msb != 15) || (pPatch_data->lsb != 0)) + { + RT_ERR_CHK(phy_common_general_reg_mmd_get(unit, port, 31, pPatch_data->addr, &rData), ret); + } + wData = REG32_FIELD_SET(rData, pPatch_data->data, pPatch_data->lsb, mask); + RT_ERR_CHK(phy_common_general_reg_mmd_set(unit, port, 31, pPatch_data->addr, wData), ret); + break; + case RTK_PATCH_OP_CMP_PHYOCP: + RT_ERR_CHK(phy_common_general_reg_mmd_get(unit, port, 31, pPatch_data->addr, &rData), ret); + PHYPATCH_COMPARE(pPatch_data->pagemmd, pPatch_data->addr, pPatch_data->msb, pPatch_data->lsb, pPatch_data->data, rData, mask); + break; + case RTK_PATCH_OP_CMP_SRAM_PHYOCP: + RT_ERR_CHK(phy_common_general_reg_mmd_set(unit, port, 31, pPatch_data->sram_rw, pPatch_data->sram_a), ret); + RT_ERR_CHK(phy_common_general_reg_mmd_get(unit, port, 31, pPatch_data->sram_rr, &rData), ret); + PHYPATCH_COMPARE(pPatch_data->pagemmd, pPatch_data->addr, pPatch_data->msb, pPatch_data->lsb, pPatch_data->data, rData, mask); + break; + + case RTK_PATCH_OP_TOP: + if ((pPatch_data->msb != 15) || (pPatch_data->lsb != 0)) + { + RT_ERR_CHK(_phy_rtl826xb_patch_top_get(unit, port, pPatch_data->pagemmd, pPatch_data->addr, &rData), ret); + } + wData = REG32_FIELD_SET(rData, pPatch_data->data, pPatch_data->lsb, mask); + RT_ERR_CHK(_phy_rtl826xb_patch_top_set(unit, port, pPatch_data->pagemmd, pPatch_data->addr, wData), ret); + break; + case RTK_PATCH_OP_CMP_TOP: + RT_ERR_CHK(_phy_rtl826xb_patch_top_get(unit, port, pPatch_data->pagemmd, pPatch_data->addr, &rData), ret); + PHYPATCH_COMPARE(pPatch_data->pagemmd, pPatch_data->addr, pPatch_data->msb, pPatch_data->lsb, pPatch_data->data, rData, mask); + break; + case RTK_PATCH_OP_CMP_SRAM_TOP: + RT_ERR_CHK(_phy_rtl826xb_patch_top_set(unit, port, pPatch_data->sram_p, pPatch_data->sram_rw, pPatch_data->sram_a), ret); + RT_ERR_CHK(_phy_rtl826xb_patch_top_get(unit, port, pPatch_data->sram_p, pPatch_data->sram_rr, &rData), ret); + PHYPATCH_COMPARE(pPatch_data->pagemmd, pPatch_data->addr, pPatch_data->msb, pPatch_data->lsb, pPatch_data->data, rData, mask); + break; + + case RTK_PATCH_OP_PSDS0: + if ((pPatch_data->msb != 15) || (pPatch_data->lsb != 0)) + { + RT_ERR_CHK(_phy_rtl826xb_patch_sds_get(unit, port, pPatch_data->pagemmd, pPatch_data->addr, &rData), ret); + } + wData = REG32_FIELD_SET(rData, pPatch_data->data, pPatch_data->lsb, mask); + RT_ERR_CHK(_phy_rtl826xb_patch_sds_set(unit, port, pPatch_data->pagemmd, pPatch_data->addr, wData, patch_mode), ret); + break; + case RTK_PATCH_OP_CMP_PSDS0: + RT_ERR_CHK(_phy_rtl826xb_patch_sds_get(unit, port, pPatch_data->pagemmd, pPatch_data->addr, &rData), ret); + PHYPATCH_COMPARE(pPatch_data->pagemmd, pPatch_data->addr, pPatch_data->msb, pPatch_data->lsb, pPatch_data->data, rData, mask); + break; + case RTK_PATCH_OP_CMP_SRAM_PSDS0: + RT_ERR_CHK(_phy_rtl826xb_patch_sds_set(unit, port, pPatch_data->sram_p, pPatch_data->sram_rw, pPatch_data->sram_a, patch_mode), ret); + RT_ERR_CHK(_phy_rtl826xb_patch_sds_get(unit, port, pPatch_data->sram_p, pPatch_data->sram_rr, &rData), ret); + PHYPATCH_COMPARE(pPatch_data->pagemmd, pPatch_data->addr, pPatch_data->msb, pPatch_data->lsb, pPatch_data->data, rData, mask); + break; + + case RTK_PATCH_OP_SKIP: + return RT_ERR_ABORT; + + default: + RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u patch_op:%u not implemented yet!\n", unit, port, pPatch_data->patch_op); + return RT_ERR_DRIVER_NOT_SUPPORTED; + } + + return ret; +} + +int32 phy_rtl826xb_patch_flow(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_flow, uint8 patch_mode) +{ + int32 ret = RT_ERR_OK; + + RT_LOG(LOG_INFO, (MOD_HAL | MOD_PHY), "[%s]U%u,P%u,flow%u\n", __FUNCTION__, unit, port, (patch_flow - PHY_PATCH_TYPE_END)); + switch (patch_flow) + { + case RTK_PATCH_TYPE_FLOW(0): + RT_ERR_CHK(_phy_rtl826xb_flow_r1(unit, port, portOffset, patch_mode), ret); + break; + case RTK_PATCH_TYPE_FLOW(1): + RT_ERR_CHK(_phy_rtl826xb_flow_r2(unit, port, portOffset, patch_mode), ret); + break; + + case RTK_PATCH_TYPE_FLOW(2): + RT_ERR_CHK(_phy_rtl826xb_flow_l1(unit, port, portOffset, patch_mode), ret); + break; + case RTK_PATCH_TYPE_FLOW(3): + RT_ERR_CHK(_phy_rtl826xb_flow_l2(unit, port, portOffset, patch_mode), ret); + break; + + case RTK_PATCH_TYPE_FLOW(4): + RT_ERR_CHK(_phy_rtl826xb_flow_n01(unit, port, portOffset, patch_mode), ret); + break; + case RTK_PATCH_TYPE_FLOW(5): + RT_ERR_CHK(_phy_rtl826xb_flow_n02(unit, port, portOffset, patch_mode), ret); + break; + + case RTK_PATCH_TYPE_FLOW(6): + RT_ERR_CHK(_phy_rtl826xb_flow_n11(unit, port, portOffset, patch_mode), ret); + break; + case RTK_PATCH_TYPE_FLOW(7): + RT_ERR_CHK(_phy_rtl826xb_flow_n12(unit, port, portOffset, patch_mode), ret); + break; + + case RTK_PATCH_TYPE_FLOW(8): + RT_ERR_CHK(_phy_rtl826xb_flow_n21(unit, port, portOffset, patch_mode), ret); + break; + case RTK_PATCH_TYPE_FLOW(9): + RT_ERR_CHK(_phy_rtl826xb_flow_n22(unit, port, portOffset, patch_mode), ret); + break; + + case RTK_PATCH_TYPE_FLOW(10): + RT_ERR_CHK(_phy_rtl826xb_flow_s(unit, port, portOffset, patch_mode), ret); + break; + + case RTK_PATCH_TYPE_FLOW(11): + RT_ERR_CHK(_phy_rtl826xb_flow_pi(unit, port, portOffset, patch_mode), ret); + break; + case RTK_PATCH_TYPE_FLOW(12): + RT_ERR_CHK(_phy_rtl826xb_flow_r12(unit, port, portOffset, patch_mode), ret); + break; + + default: + return RT_ERR_INPUT; + } + return RT_ERR_OK; +} + +int32 phy_rtl826xb_patch_db_init(uint32 unit, rtk_port_t port, rt_phy_patch_db_t **pPhy_patchDb) +{ + int32 ret = RT_ERR_OK; + rt_phy_patch_db_t *patch_db = NULL; + uint32 rData = 0; + + patch_db = osal_alloc(sizeof(rt_phy_patch_db_t)); + RT_PARAM_CHK(NULL == patch_db, RT_ERR_MEM_ALLOC); + osal_memset(patch_db, 0x0, sizeof(rt_phy_patch_db_t)); + + /* patch callback */ + patch_db->fPatch_op = phy_rtl826xb_patch_op; + patch_db->fPatch_flow = phy_rtl826xb_patch_flow; + + /* patch table */ + RT_ERR_CHK(phy_common_general_reg_mmd_get(unit, port, 30, 0x104, &rData), ret); + if ((rData & 0x7) == 0x0) + { + /* patch */ + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 0, RTK_PATCH_TYPE_FLOW(12), NULL); + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 1, PHY_PATCH_TYPE_NCTL0, rtl8264b_nctl0_conf); + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 2, PHY_PATCH_TYPE_NCTL1, rtl8264b_nctl1_conf); + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 3, PHY_PATCH_TYPE_NCTL2, rtl8264b_nctl2_conf); + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 4, PHY_PATCH_TYPE_UC2, rtl8264b_uc2_conf); + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 5, PHY_PATCH_TYPE_UC, rtl8264b_uc_conf); + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 6, PHY_PATCH_TYPE_DATARAM, rtl8264b_dataram_conf); + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 7, RTK_PATCH_TYPE_FLOW(1), NULL); + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 8, RTK_PATCH_TYPE_FLOW(2), NULL); + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 9, PHY_PATCH_TYPE_ALGXG, rtl8264b_algxg_conf); + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 10, PHY_PATCH_TYPE_ALG1G, rtl8264b_alg_giga_conf); + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 11, PHY_PATCH_TYPE_NORMAL, rtl8264b_normal_conf); + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 12, PHY_PATCH_TYPE_TOP, rtl8264b_top_conf); + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 13, PHY_PATCH_TYPE_SDS, rtl8264b_sds_conf); + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 14, PHY_PATCH_TYPE_AFE, rtl8264b_afe_conf); + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 15, PHY_PATCH_TYPE_RTCT, rtl8264b_rtct_conf); + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 16, RTK_PATCH_TYPE_FLOW(3), NULL); + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 17, RTK_PATCH_TYPE_FLOW(11), NULL); + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 18, RTK_PATCH_TYPE_FLOW(10), NULL); + + /* compare */ + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 0, PHY_PATCH_TYPE_TOP, rtl8264b_top_conf); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 1, PHY_PATCH_TYPE_SDS, rtl8264b_sds_conf); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 2, PHY_PATCH_TYPE_AFE, rtl8264b_afe_conf); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 3, RTK_PATCH_TYPE_FLOW(4), NULL); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 4, PHY_PATCH_TYPE_NCTL0, rtl8264b_nctl0_conf); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 5, RTK_PATCH_TYPE_FLOW(5), NULL); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 6, RTK_PATCH_TYPE_FLOW(6), NULL); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 7, PHY_PATCH_TYPE_NCTL1, rtl8264b_nctl1_conf); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 8, RTK_PATCH_TYPE_FLOW(7), NULL); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 9, RTK_PATCH_TYPE_FLOW(8), NULL); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 10, PHY_PATCH_TYPE_NCTL2, rtl8264b_nctl2_conf); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 11, RTK_PATCH_TYPE_FLOW(9), NULL); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 12, PHY_PATCH_TYPE_UC, rtl8264b_uc_conf); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 13, PHY_PATCH_TYPE_UC2, rtl8264b_uc2_conf); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 14, RTK_PATCH_TYPE_FLOW(12), NULL); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 15, PHY_PATCH_TYPE_DATARAM, rtl8264b_dataram_conf); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 16, RTK_PATCH_TYPE_FLOW(1), NULL); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 17, PHY_PATCH_TYPE_ALGXG, rtl8264b_algxg_conf); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 18, PHY_PATCH_TYPE_ALG1G, rtl8264b_alg_giga_conf); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 19, PHY_PATCH_TYPE_NORMAL, rtl8264b_normal_conf); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 20, PHY_PATCH_TYPE_RTCT, rtl8264b_rtct_conf); + } + else + { + /* patch */ + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 0, RTK_PATCH_TYPE_FLOW(0), NULL); + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 1, PHY_PATCH_TYPE_NCTL0, rtl8261n_c_nctl0_conf); + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 2, PHY_PATCH_TYPE_NCTL1, rtl8261n_c_nctl1_conf); + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 3, PHY_PATCH_TYPE_NCTL2, rtl8261n_c_nctl2_conf); + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 4, PHY_PATCH_TYPE_UC2, rtl8261n_c_uc2_conf); + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 5, PHY_PATCH_TYPE_UC, rtl8261n_c_uc_conf); + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 6, PHY_PATCH_TYPE_DATARAM, rtl8261n_c_dataram_conf); + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 7, RTK_PATCH_TYPE_FLOW(1), NULL); + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 8, RTK_PATCH_TYPE_FLOW(2), NULL); + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 9, PHY_PATCH_TYPE_ALGXG, rtl8261n_c_algxg_conf); + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 10, PHY_PATCH_TYPE_ALG1G, rtl8261n_c_alg_giga_conf); + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 11, PHY_PATCH_TYPE_NORMAL, rtl8261n_c_normal_conf); + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 12, PHY_PATCH_TYPE_TOP, rtl8261n_c_top_conf); + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 13, PHY_PATCH_TYPE_SDS, rtl8261n_c_sds_conf); + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 14, PHY_PATCH_TYPE_AFE, rtl8261n_c_afe_conf); + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 15, PHY_PATCH_TYPE_RTCT, rtl8261n_c_rtct_conf); + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 16, RTK_PATCH_TYPE_FLOW(3), NULL); + PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 17, RTK_PATCH_TYPE_FLOW(10), NULL); + + /* compare */ + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 0, PHY_PATCH_TYPE_TOP, rtl8261n_c_top_conf); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 1, PHY_PATCH_TYPE_SDS, rtl8261n_c_sds_conf); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 2, PHY_PATCH_TYPE_AFE, rtl8261n_c_afe_conf); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 3, RTK_PATCH_TYPE_FLOW(4), NULL); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 4, PHY_PATCH_TYPE_NCTL0, rtl8261n_c_nctl0_conf); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 5, RTK_PATCH_TYPE_FLOW(5), NULL); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 6, RTK_PATCH_TYPE_FLOW(6), NULL); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 7, PHY_PATCH_TYPE_NCTL1, rtl8261n_c_nctl1_conf); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 8, RTK_PATCH_TYPE_FLOW(7), NULL); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 9, RTK_PATCH_TYPE_FLOW(8), NULL); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 10, PHY_PATCH_TYPE_NCTL2, rtl8261n_c_nctl2_conf); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 11, RTK_PATCH_TYPE_FLOW(9), NULL); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 12, PHY_PATCH_TYPE_UC, rtl8261n_c_uc_conf); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 13, PHY_PATCH_TYPE_UC2, rtl8261n_c_uc2_conf); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 14, RTK_PATCH_TYPE_FLOW(0), NULL); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 15, PHY_PATCH_TYPE_DATARAM, rtl8261n_c_dataram_conf); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 16, RTK_PATCH_TYPE_FLOW(1), NULL); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 17, PHY_PATCH_TYPE_ALGXG, rtl8261n_c_algxg_conf); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 18, PHY_PATCH_TYPE_ALG1G, rtl8261n_c_alg_giga_conf); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 19, PHY_PATCH_TYPE_NORMAL, rtl8261n_c_normal_conf); + PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 20, PHY_PATCH_TYPE_RTCT, rtl8261n_c_rtct_conf); + } + *pPhy_patchDb = patch_db; + return ret; +} + +/* Function Name: + * phy_rtl826xb_patch + * Description: + * apply initial patch data to PHY + * Input: + * unit - unit id + * baseport - base port id on the PHY chip + * portOffset - the index offset base on baseport for the port to patch + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_SUPPORTED + * RT_ERR_ABORT + * Note: + * None + */ +int32 phy_rtl826xb_patch(uint32 unit, rtk_port_t port, uint8 portOffset) +{ + return phy_patch( unit, port, portOffset, PHY_PATCH_MODE_NORMAL); +} + +/* Function Name: + * phy_rtl826xb_broadcast_patch + * Description: + * apply patch data to PHY + * Input: + * unit - unit id + * baseport - base port id on the PHY chip + * portOffset - the index offset base on baseport for the port to patch + * perChip - 1 for per-chip mode, 0 for per-bus mode + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_SUPPORTED + * RT_ERR_ABORT + * Note: + * None + */ +int32 phy_rtl826xb_broadcast_patch(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 perChip) +{ + int32 ret = 0; + if (perChip == 0) + { + ret = phy_patch(unit, port, portOffset, PHY_PATCH_MODE_BCAST_BUS); + } + else + { + ret = phy_patch(unit, port, portOffset, PHY_PATCH_MODE_BCAST); + } + return ret; +} + diff --git a/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/phy_rtl826xb_patch.h b/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/phy_rtl826xb_patch.h new file mode 100644 index 00000000000..c2311ef2bf4 --- /dev/null +++ b/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/phy_rtl826xb_patch.h @@ -0,0 +1,63 @@ +/* + * SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved. + */ + +#ifndef __HAL_PHY_PHY_RTL826XB_PATCH_H__ +#define __HAL_PHY_PHY_RTL826XB_PATCH_H__ + +/* + * Include Files + */ +#if defined(RTK_PHYDRV_IN_LINUX) + #include "rtk_osal.h" + #include "rtk_phylib_def.h" +#else + #include + #include +#endif + +/* Function Name: + * phy_rtl826xb_patch + * Description: + * apply patch data to PHY + * Input: + * unit - unit id + * baseport - base port id on the PHY chip + * portOffset - the index offset base on baseport for the port to patch + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_SUPPORTED + * RT_ERR_ABORT + * Note: + * None + */ +extern int32 phy_rtl826xb_patch(uint32 unit, rtk_port_t baseport, uint8 portOffset); + +/* Function Name: + * phy_rtl826xb_broadcast_patch + * Description: + * apply patch data to PHY + * Input: + * unit - unit id + * baseport - base port id on the PHY chip + * portOffset - the index offset base on baseport for the port to patch + * perChip - 1 for per-chip mode, 0 for per-bus mode + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_SUPPORTED + * RT_ERR_ABORT + * Note: + * None + */ +extern int32 phy_rtl826xb_broadcast_patch(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 perChip); + +extern int32 phy_rtl826xb_patch_db_init(uint32 unit, rtk_port_t port, rt_phy_patch_db_t **pPhy_patchDb); +#endif /* __HAL_PHY_PHY_RTL826XB_PATCH_H__ */ diff --git a/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/rtk_osal.c b/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/rtk_osal.c new file mode 100644 index 00000000000..bf3ac4b1244 --- /dev/null +++ b/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/rtk_osal.c @@ -0,0 +1,56 @@ +/* + * SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved. + */ + +#include "type.h" +#include "error.h" +#include "rtk_phylib_def.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +int32 +osal_time_usecs_get(osal_usecs_t *pUsec) +{ + struct timespec64 ts; + + RT_PARAM_CHK((NULL == pUsec), RT_ERR_NULL_POINTER); + + ktime_get_ts64(&ts); + *pUsec = (osal_usecs_t)((ts.tv_sec * USEC_PER_SEC) + (ts.tv_nsec / NSEC_PER_USEC)); + return RT_ERR_OK; +} + +void * +osal_alloc(uint32 size) +{ + void *p; + p = kmalloc((size_t)size, GFP_ATOMIC); + return p; +} + +int32 +phy_common_general_reg_mmd_get(uint32 unit, rtk_port_t port, uint32 mmdAddr, uint32 mmdReg, uint32 *pData) +{ + int32 rData = 0; + rData = phy_read_mmd(port, mmdAddr, mmdReg); + if (rData < 0) + return RT_ERR_FAILED; + *pData = (uint32)rData; + return RT_ERR_OK; +} + +int32 +phy_common_general_reg_mmd_set(uint32 unit, rtk_port_t port, uint32 mmdAddr, uint32 mmdReg, uint32 data) +{ + int ret = phy_write_mmd(port, mmdAddr, mmdReg, data); + return (ret < 0) ? RT_ERR_FAILED : RT_ERR_OK; +} diff --git a/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/rtk_osal.h b/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/rtk_osal.h new file mode 100644 index 00000000000..edf674611ef --- /dev/null +++ b/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/rtk_osal.h @@ -0,0 +1,99 @@ +/* + * SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved. + */ + +#ifndef __RTK_PHY_OSAL_H +#define __RTK_PHY_OSAL_H + +#include +#include +#include "type.h" +#include "error.h" +#include "phy_patch.h" +#include "rtk_phylib.h" + +#ifdef PHYPATCH_DB_GET + #undef PHYPATCH_DB_GET +#endif + +#define PHYPATCH_DB_GET(_unit, _pPhy_device, _pPatchDb) \ + do { \ + struct rtk_phy_priv *_pPriv = (_pPhy_device)->priv; \ + rt_phy_patch_db_t *_pDb = _pPriv->patch; _pPatchDb = _pDb; \ + /*printk("[PHYPATCH_DB_GET] ? [%s]\n", (_pDb != NULL) ? "E":"N");*/ \ + } while(0) + +#define HWP_9300_FAMILY_ID(_unit) 0 +#define HWP_9310_FAMILY_ID(_unit) 0 +#define RTK_9300_FAMILY_ID(_unit) 0 +#define RTK_9310_FAMILY_ID(_unit) 0 +#define RTK_9311B_FAMILY_ID(_unit) 0 +#define RTK_9330_FAMILY_ID(_unit) 0 + +#ifndef WAIT_COMPLETE_VAR +#define WAIT_COMPLETE_VAR() \ + osal_usecs_t _t, _now, _t_wait=0, _timeout; \ + int32 _chkCnt=0; + +#define WAIT_COMPLETE(_timeout_us) \ + _timeout = _timeout_us; \ + for(osal_time_usecs_get(&_t),osal_time_usecs_get(&_now),_t_wait=0,_chkCnt=0 ; \ + (_t_wait <= _timeout); \ + osal_time_usecs_get(&_now), _chkCnt++, _t_wait += ((_now >= _t) ? (_now - _t) : (0xFFFFFFFF - _t + _now)),_t = _now \ + ) + +#define WAIT_COMPLETE_IS_TIMEOUT() (_t_wait > _timeout) +#endif + +/* OSAL */ +#include +int32 osal_time_usecs_get(osal_usecs_t *pUsec); +void *osal_alloc(uint32 size); +#define osal_time_mdelay mdelay + +#include /* for Kernel Space */ +#include +#include +#define osal_strlen strlen +#define osal_strcmp strcmp +#define osal_strcpy strcpy +#define osal_strncpy strncpy +#define osal_strcat strcat +#define osal_strchr strchr +#define osal_memset memset +#define osal_memcpy memcpy +#define osal_memcmp memcmp +#define osal_strdup strdup +#define osal_strncmp strncmp +#define osal_strstr strstr +#define osal_strtok strtok +#define osal_strtok_r strtok_r +#define osal_toupper toupper + +#define osal_printf printk + +/* HWP */ +#define HWP_PORT_SMI(unit, port) 0 +#define HWP_PHY_MODEL_BY_PORT(unit, port) 0 +#define HWP_PHY_ADDR(unit, port) 0 +#define HWP_PHY_BASE_MACID(unit, p) 0 +#define HWP_PORT_TRAVS_EXCEPT_CPU(unit, p) if (bcast_phyad < 0x1F && p != NULL) + + +/* RT_LOG */ +//#define RT_LOG(level, module, fmt, args...) do { printk("RT_LOG:"fmt, ## args); } while(0) +#define RT_LOG(level, module, fmt, args...) do {} while(0) +#define RT_ERR(error_code, module, fmt, args...) do {} while(0) +#define RT_INIT_ERR(error_code, module, fmt, args...) do {} while(0) +#define RT_INIT_MSG(fmt, args...) do {} while(0) + +#define phy_826xb_ctrl_set(unit, p, RTK_PHY_CTRL_MIIM_BCAST_PHYAD, bcast_phyad) 0 + +/* reg access */ +int32 phy_common_general_reg_mmd_get(uint32 unit, rtk_port_t port, uint32 mmdAddr, uint32 mmdReg, uint32 *pData); +int32 phy_common_general_reg_mmd_set(uint32 unit, rtk_port_t port, uint32 mmdAddr, uint32 mmdReg, uint32 data); + + +#endif /* __RTK_PHY_OSAL_H */ diff --git a/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/rtk_phy.c b/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/rtk_phy.c new file mode 100644 index 00000000000..2818a2736b7 --- /dev/null +++ b/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/rtk_phy.c @@ -0,0 +1,282 @@ +/* + * SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved. + */ + +#include +#include + +#include "phy_rtl826xb_patch.h" +#include "rtk_phylib_rtl826xb.h" +#include "rtk_phylib.h" + +#define REALTEK_PHY_ID_RTL8261N 0x001CCAF3 +#define REALTEK_PHY_ID_RTL8264B 0x001CC813 + +static int rtl826xb_get_features(struct phy_device *phydev) +{ + int ret; + ret = genphy_c45_pma_read_abilities(phydev); + if (ret) + return ret; + + linkmode_or(phydev->supported, phydev->supported, PHY_BASIC_FEATURES); + + + linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, + phydev->supported); + linkmode_set_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, + phydev->supported); + + /* not support 10M modes */ + linkmode_clear_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, + phydev->supported); + linkmode_clear_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, + phydev->supported); + + return 0; +} + +static int rtl826xb_probe(struct phy_device *phydev) +{ + struct rtk_phy_priv *priv = NULL; + + priv = devm_kzalloc(&phydev->mdio.dev, sizeof(struct rtk_phy_priv), GFP_KERNEL); + if (!priv) + { + return -ENOMEM; + } + memset(priv, 0, sizeof(struct rtk_phy_priv)); + + if (phy_rtl826xb_patch_db_init(0, phydev, &(priv->patch)) != RT_ERR_OK) + return -ENOMEM; + + priv->phytype = (phydev->drv->phy_id == REALTEK_PHY_ID_RTL8261N) ? (RTK_PHYLIB_RTL8261N) : (RTK_PHYLIB_RTL8264B); + priv->isBasePort = (phydev->drv->phy_id == REALTEK_PHY_ID_RTL8261N) ? (1) : (((phydev->mdio.addr % 4) == 0) ? (1) : (0)); + phydev->priv = priv; + + return 0; +} + +static int rtkphy_config_init(struct phy_device *phydev) +{ + int ret = 0; + switch (phydev->drv->phy_id) + { + case REALTEK_PHY_ID_RTL8261N: + case REALTEK_PHY_ID_RTL8264B: + phydev_info(phydev, "%s:%u [RTL8261N/RTL826XB] phy_id: 0x%X PHYAD:%d\n", __FUNCTION__, __LINE__, phydev->drv->phy_id, phydev->mdio.addr); + + + #if 1 /* toggle reset */ + phy_modify_mmd_changed(phydev, 30, 0x145, BIT(0) , 1); + phy_modify_mmd_changed(phydev, 30, 0x145, BIT(0) , 0); + mdelay(30); + #endif + + ret = phy_patch(0, phydev, 0, PHY_PATCH_MODE_NORMAL); + if (ret) + { + phydev_err(phydev, "%s:%u [RTL8261N/RTL826XB] patch failed!! 0x%X\n", __FUNCTION__, __LINE__, ret); + return ret; + } + #if 0 /* Debug: patch check */ + ret = phy_patch(0, phydev, 0, PHY_PATCH_MODE_CMP); + if (ret) + { + phydev_err(phydev, "%s:%u [RTL8261N/RTL826XB] phy_patch failed!! 0x%X\n", __FUNCTION__, __LINE__, ret); + return ret; + } + printk("[%s,%u] patch chk %s\n", __FUNCTION__, __LINE__, (ret == 0) ? "PASS" : "FAIL"); + #endif + #if 0 /* Debug: USXGMII*/ + { + uint32 data = 0; + rtk_phylib_826xb_sds_read(phydev, 0x07, 0x10, 15, 0, &data); + printk("[%s,%u] SDS 0x07, 0x10 : 0x%X\n", __FUNCTION__, __LINE__, data); + rtk_phylib_826xb_sds_read(phydev, 0x06, 0x12, 15, 0, &data); + printk("[%s,%u] SDS 0x06, 0x12 : 0x%X\n", __FUNCTION__, __LINE__, data); + } + { + u16 sdspage = 0x5, sdsreg = 0x0; + u16 regData = (sdspage & 0x3f) | ((sdsreg & 0x1f) << 6) | BIT(15); + u16 readData = 0; + phy_write_mmd(phydev, 30, 323, regData); + do + { + udelay(10); + readData = phy_read_mmd(phydev, 30, 323); + } while ((readData & BIT(15)) != 0); + readData = phy_read_mmd(phydev, 30, 322); + printk("[%s,%d] sds link [%s] (0x%X)\n", __FUNCTION__, __LINE__, (readData & BIT(12)) ? "UP" : "DOWN", readData); + } + #endif + + break; + default: + phydev_err(phydev, "%s:%u Unknow phy_id: 0x%X\n", __FUNCTION__, __LINE__, phydev->drv->phy_id); + return -EPERM; + } + + return ret; +} + +static int rtkphy_c45_suspend(struct phy_device *phydev) +{ + int ret = 0; + + ret = rtk_phylib_c45_power_low(phydev); + + phydev->speed = SPEED_UNKNOWN; + phydev->duplex = DUPLEX_UNKNOWN; + phydev->pause = 0; + phydev->asym_pause = 0; + + return ret; +} + +static int rtkphy_c45_resume(struct phy_device *phydev) +{ + return rtk_phylib_c45_power_normal(phydev); +} + +static int rtkphy_c45_config_aneg(struct phy_device *phydev) +{ + bool changed = false; + u16 reg = 0; + int ret = 0; + + phydev->mdix_ctrl = ETH_TP_MDI_AUTO; + if (phydev->autoneg == AUTONEG_DISABLE) + return genphy_c45_pma_setup_forced(phydev); + + ret = genphy_c45_an_config_aneg(phydev); + if (ret < 0) + return ret; + if (ret > 0) + changed = true; + + reg = 0; + if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, + phydev->advertising)) + reg |= BIT(9); + + if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, + phydev->advertising)) + reg |= BIT(8); + + ret = phy_modify_mmd_changed(phydev, MDIO_MMD_VEND2, 0xA412, + BIT(9) | BIT(8) , reg); + if (ret < 0) + return ret; + if (ret > 0) + changed = true; + + return genphy_c45_check_and_restart_aneg(phydev, changed); +} + +static int rtkphy_c45_aneg_done(struct phy_device *phydev) +{ + return genphy_c45_aneg_done(phydev); +} + +static int rtkphy_c45_read_status(struct phy_device *phydev) +{ + int ret = 0, status = 0; + phydev->speed = SPEED_UNKNOWN; + phydev->duplex = DUPLEX_UNKNOWN; + phydev->pause = 0; + phydev->asym_pause = 0; + + ret = genphy_c45_read_link(phydev); + if (ret) + return ret; + + if (phydev->autoneg == AUTONEG_ENABLE) + { + linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, + phydev->lp_advertising); + + ret = genphy_c45_read_lpa(phydev); + if (ret) + return ret; + + status = phy_read_mmd(phydev, 31, 0xA414); + if (status < 0) + return status; + linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, + phydev->lp_advertising, status & BIT(11)); + + phy_resolve_aneg_linkmode(phydev); + } + else + { + ret = genphy_c45_read_pma(phydev); + } + + /* mdix*/ + status = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_10GBT_SWAPPOL); + if (status < 0) + return status; + + switch (status & 0x3) + { + case MDIO_PMA_10GBT_SWAPPOL_ABNX | MDIO_PMA_10GBT_SWAPPOL_CDNX: + phydev->mdix = ETH_TP_MDI; + break; + + case 0: + phydev->mdix = ETH_TP_MDI_X; + break; + + default: + phydev->mdix = ETH_TP_MDI_INVALID; + break; + } + + return ret; +} + + +static struct phy_driver rtk_phy_drivers[] = { + { + PHY_ID_MATCH_EXACT(REALTEK_PHY_ID_RTL8261N), + .name = "Realtek RTL8261N", + .get_features = rtl826xb_get_features, + .config_init = rtkphy_config_init, + .probe = rtl826xb_probe, + .suspend = rtkphy_c45_suspend, + .resume = rtkphy_c45_resume, + .config_aneg = rtkphy_c45_config_aneg, + .aneg_done = rtkphy_c45_aneg_done, + .read_status = rtkphy_c45_read_status, + }, + { + PHY_ID_MATCH_EXACT(REALTEK_PHY_ID_RTL8264B), + .name = "Realtek RTL8264B", + .get_features = rtl826xb_get_features, + .config_init = rtkphy_config_init, + .probe = rtl826xb_probe, + .suspend = rtkphy_c45_suspend, + .resume = rtkphy_c45_resume, + .config_aneg = rtkphy_c45_config_aneg, + .aneg_done = rtkphy_c45_aneg_done, + .read_status = rtkphy_c45_read_status, + }, +}; + +module_phy_driver(rtk_phy_drivers); + + +static struct mdio_device_id __maybe_unused rtk_phy_tbl[] = { + { PHY_ID_MATCH_EXACT(REALTEK_PHY_ID_RTL8261N) }, + { PHY_ID_MATCH_EXACT(REALTEK_PHY_ID_RTL8264B) }, + { }, +}; + +MODULE_DEVICE_TABLE(mdio, rtk_phy_tbl); + +MODULE_AUTHOR("Realtek"); +MODULE_DESCRIPTION("Realtek PHY drivers"); +MODULE_LICENSE("GPL"); diff --git a/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/rtk_phylib.c b/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/rtk_phylib.c new file mode 100644 index 00000000000..7dd593ce72d --- /dev/null +++ b/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/rtk_phylib.c @@ -0,0 +1,108 @@ +/* + * SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved. + */ + +#include "rtk_phylib.h" +#include + + +/* OSAL */ + +void rtk_phylib_mdelay(uint32 msec) +{ +#if defined(RTK_PHYDRV_IN_LINUX) + mdelay(msec); +#else + osal_time_mdelay(msec); +#endif +} + + +void rtk_phylib_udelay(uint32 usec) +{ +#if defined(RTK_PHYDRV_IN_LINUX) + if (1000 <= usec) + { + mdelay(usec/1000); + usec = usec % 1000; + } + udelay(usec); +#else + osal_time_udelay(usec); +#endif +} + + +/* Register Access APIs */ +int32 rtk_phylib_mmd_write(rtk_phydev *phydev, uint32 mmd, uint32 reg, uint8 msb, uint8 lsb, uint32 data) +{ + int32 ret = 0; + uint32 mask = 0; + mask = UINT32_BITS_MASK(msb,lsb); + +#if defined(RTK_PHYDRV_IN_LINUX) + ret = phy_modify_mmd(phydev, mmd, reg, mask, data); +#else + { + uint32 rData = 0, wData = 0; + if ((msb != 15) || (lsb != 0)) + { + if ((ret = phy_common_general_reg_mmd_get(phydev->unit, phydev->port, page, reg, &rData)) != RT_ERR_OK) + return ret; + } + wData = REG32_FIELD_SET(rData, data, lsb, mask); + ret = phy_common_general_reg_mmd_set(phydev->unit, phydev->port, page, reg, wData); + } +#endif + + return ret; +} + +int32 rtk_phylib_mmd_read(rtk_phydev *phydev, uint32 mmd, uint32 reg, uint8 msb, uint8 lsb, uint32 *pData) +{ + int32 ret = 0; + uint32 rData = 0; + uint32 mask = 0; + mask = UINT32_BITS_MASK(msb,lsb); + +#if defined(RTK_PHYDRV_IN_LINUX) + rData = phy_read_mmd(phydev, mmd, reg); +#else + { + ret = phy_common_general_reg_mmd_get(phydev->unit, phydev->port, page, reg, &rData); + } +#endif + + *pData = REG32_FIELD_GET(rData, lsb, mask); + return ret; +} + +/* Function Driver */ + +int32 rtk_phylib_c45_power_normal(rtk_phydev *phydev) +{ + int32 ret = 0; + RTK_PHYLIB_ERR_CHK(rtk_phylib_mmd_write(phydev, 1, 0, 11, 11, 0)); + + return 0; +} + +int32 rtk_phylib_c45_power_low(rtk_phydev *phydev) +{ + int32 ret = 0; + RTK_PHYLIB_ERR_CHK(rtk_phylib_mmd_write(phydev, 1, 0, 11, 11, 1)); + + return 0; +} + +int32 rtk_phylib_c45_pcs_loopback(rtk_phydev *phydev, uint32 enable) +{ + int32 ret = 0; + RTK_PHYLIB_ERR_CHK(rtk_phylib_mmd_write(phydev, 3, 0, 14, 14, (enable == 0) ? 0 : 1)); + + return 0; +} + + diff --git a/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/rtk_phylib.h b/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/rtk_phylib.h new file mode 100644 index 00000000000..70eb8e48edc --- /dev/null +++ b/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/rtk_phylib.h @@ -0,0 +1,101 @@ +/* + * SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved. + */ + +#ifndef __RTK_PHYLIB_H +#define __RTK_PHYLIB_H + +#if defined(RTK_PHYDRV_IN_LINUX) + #include "type.h" + #include "rtk_phylib_def.h" +#else + //#include SDK headers +#endif + +#if defined(RTK_PHYDRV_IN_LINUX) + #define PR_INFO(_fmt, _args...) pr_info(_fmt, ##_args) + #define PR_DBG(_fmt, _args...) pr_debug(_fmt, ##_args) + #define PR_ERR(_fmt, _args...) pr_err("ERROR: "_fmt, ##_args) + + #define RTK_PHYLIB_ERR_FAILED (-EPERM) + #define RTK_PHYLIB_ERR_INPUT (-EINVAL) + #define RTK_PHYLIB_ERR_EXCEEDS_CAPACITY (-ENOSPC) + #define RTK_PHYLIB_ERR_TIMEOUT (-ETIME) + #define RTK_PHYLIB_ERR_ENTRY_NOTFOUND (-ENODATA) +#else + #define PR_INFO(_fmt, _args...) RT_LOG(LOG_INFO, (MOD_HAL|MOD_PHY), _fmt, ##_args) + #define PR_DBG(_fmt, _args...) RT_LOG(LOG_DEBUG, (MOD_HAL|MOD_PHY), _fmt, ##_args) + #define PR_ERR(_fmt, _args...) RT_LOG(LOG_MAJOR_ERR, (MOD_HAL|MOD_PHY), _fmt, ##_args) + + #define RTK_PHYLIB_ERR_FAILED (RT_ERR_FAILED) + #define RTK_PHYLIB_ERR_INPUT (RT_ERR_INPUT) + #define RTK_PHYLIB_ERR_EXCEEDS_CAPACITY (RT_ERR_EXCEEDS_CAPACITY) + #define RTK_PHYLIB_ERR_TIMEOUT (RT_ERR_BUSYWAIT_TIMEOUT) + #define RTK_PHYLIB_ERR_ENTRY_NOTFOUND (RT_ERR_ENTRY_NOTFOUND) +#endif + +typedef enum rtk_phylib_phy_e +{ + RTK_PHYLIB_NONE, + RTK_PHYLIB_RTL8261N, + RTK_PHYLIB_RTL8264B, + RTK_PHYLIB_END +} rtk_phylib_phy_t; + +struct rtk_phy_priv { + rtk_phylib_phy_t phytype; + uint8 isBasePort; + rt_phy_patch_db_t *patch; +}; + +#if defined(RTK_PHYDRV_IN_LINUX) + typedef struct phy_device rtk_phydev; +#else + struct rtk_phy_dev_s + { + uint32 unit; + rtk_port_t port; + + struct rtk_phy_priv *priv; + }; + typedef struct rtk_phy_dev_s rtk_phydev; +#endif + +#define RTK_PHYLIB_ERR_CHK(op)\ +do {\ + if ((ret = (op)) != 0)\ + return ret;\ +} while(0) + +#define RTK_PHYLIB_VAL_TO_BYTE_ARRAY(_val, _valbytes, _array, _start, _bytes)\ +do{\ + uint32 _i = 0;\ + for (_i = 0; _i < _bytes; _i++)\ + _array[_start+_i] = (_val >> (8* (_valbytes - _i - 1)));\ +}while(0) + +#define RTK_PHYLIB_BYTE_ARRAY_TO_VAL(_val, _array, _start, _bytes)\ +do{\ + uint32 _i = 0;\ + for (_i = 0; _i < _bytes; _i++)\ + _val = (_val << 8) | _array[_start + _i];\ +}while(0) + + +/* OSAL */ +void rtk_phylib_mdelay(uint32 msec); +void rtk_phylib_udelay(uint32 usec); + +/* Register Access APIs */ +int32 rtk_phylib_mmd_write(rtk_phydev *phydev, uint32 mmd, uint32 reg, uint8 msb, uint8 lsb, uint32 data); +int32 rtk_phylib_mmd_read(rtk_phydev *phydev, uint32 mmd, uint32 reg, uint8 msb, uint8 lsb, uint32 *pData); + +/* Function Driver */ +int32 rtk_phylib_c45_power_normal(rtk_phydev *phydev); +int32 rtk_phylib_c45_power_low(rtk_phydev *phydev); +int32 rtk_phylib_c45_pcs_loopback(rtk_phydev *phydev, uint32 enable); + + +#endif /* __RTK_PHYLIB_H */ diff --git a/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/rtk_phylib_def.h b/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/rtk_phylib_def.h new file mode 100644 index 00000000000..f49f0b547cc --- /dev/null +++ b/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/rtk_phylib_def.h @@ -0,0 +1,166 @@ +/* + * SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved. + */ +#ifndef __RTK_PHYLIB_DEF_H +#define __RTK_PHYLIB_DEF_H + +#include "type.h" + +//#define PHY_C22_MMD_PAGE 0 +#define PHY_C22_MMD_PAGE 0x0A41 +#define PHY_C22_MMD_DEV_REG 13 +#define PHY_C22_MMD_ADD_REG 14 + +/* MDIO Manageable Device(MDD) address*/ +#define PHY_MMD_PMAPMD 1 +#define PHY_MMD_PCS 3 +#define PHY_MMD_AN 7 +#define PHY_MMD_VEND1 30 /* Vendor specific 1 */ +#define PHY_MMD_VEND2 31 /* Vendor specific 2 */ + +#define BIT_0 0x00000001U +#define BIT_1 0x00000002U +#define BIT_2 0x00000004U +#define BIT_3 0x00000008U +#define BIT_4 0x00000010U +#define BIT_5 0x00000020U +#define BIT_6 0x00000040U +#define BIT_7 0x00000080U +#define BIT_8 0x00000100U +#define BIT_9 0x00000200U +#define BIT_10 0x00000400U +#define BIT_11 0x00000800U +#define BIT_12 0x00001000U +#define BIT_13 0x00002000U +#define BIT_14 0x00004000U +#define BIT_15 0x00008000U +#define BIT_16 0x00010000U +#define BIT_17 0x00020000U +#define BIT_18 0x00040000U +#define BIT_19 0x00080000U +#define BIT_20 0x00100000U +#define BIT_21 0x00200000U +#define BIT_22 0x00400000U +#define BIT_23 0x00800000U +#define BIT_24 0x01000000U +#define BIT_25 0x02000000U +#define BIT_26 0x04000000U +#define BIT_27 0x08000000U +#define BIT_28 0x10000000U +#define BIT_29 0x20000000U +#define BIT_30 0x40000000U +#define BIT_31 0x80000000U + +#define MASK_1_BITS (BIT_1 - 1) +#define MASK_2_BITS (BIT_2 - 1) +#define MASK_3_BITS (BIT_3 - 1) +#define MASK_4_BITS (BIT_4 - 1) +#define MASK_5_BITS (BIT_5 - 1) +#define MASK_6_BITS (BIT_6 - 1) +#define MASK_7_BITS (BIT_7 - 1) +#define MASK_8_BITS (BIT_8 - 1) +#define MASK_9_BITS (BIT_9 - 1) +#define MASK_10_BITS (BIT_10 - 1) +#define MASK_11_BITS (BIT_11 - 1) +#define MASK_12_BITS (BIT_12 - 1) +#define MASK_13_BITS (BIT_13 - 1) +#define MASK_14_BITS (BIT_14 - 1) +#define MASK_15_BITS (BIT_15 - 1) +#define MASK_16_BITS (BIT_16 - 1) +#define MASK_17_BITS (BIT_17 - 1) +#define MASK_18_BITS (BIT_18 - 1) +#define MASK_19_BITS (BIT_19 - 1) +#define MASK_20_BITS (BIT_20 - 1) +#define MASK_21_BITS (BIT_21 - 1) +#define MASK_22_BITS (BIT_22 - 1) +#define MASK_23_BITS (BIT_23 - 1) +#define MASK_24_BITS (BIT_24 - 1) +#define MASK_25_BITS (BIT_25 - 1) +#define MASK_26_BITS (BIT_26 - 1) +#define MASK_27_BITS (BIT_27 - 1) +#define MASK_28_BITS (BIT_28 - 1) +#define MASK_29_BITS (BIT_29 - 1) +#define MASK_30_BITS (BIT_30 - 1) +#define MASK_31_BITS (BIT_31 - 1) + +#define REG32_FIELD_SET(_data, _val, _fOffset, _fMask) ((_data & ~(_fMask)) | ((_val << (_fOffset)) & (_fMask))) +#define REG32_FIELD_GET(_data, _fOffset, _fMask) ((_data & (_fMask)) >> (_fOffset)) +#define UINT32_BITS_MASK(_mBit, _lBit) ((0xFFFFFFFF >> (31 - _mBit)) ^ ((1 << _lBit) - 1)) + +typedef struct phy_device * rtk_port_t; + +#if 1 /* ss\sdk\include\hal\phy\phydef.h */ +/* unified patch format */ +typedef enum rtk_phypatch_type_e +{ + PHY_PATCH_TYPE_NONE = 0, + PHY_PATCH_TYPE_TOP = 1, + PHY_PATCH_TYPE_SDS, + PHY_PATCH_TYPE_AFE, + PHY_PATCH_TYPE_UC, + PHY_PATCH_TYPE_UC2, + PHY_PATCH_TYPE_NCTL0, + PHY_PATCH_TYPE_NCTL1, + PHY_PATCH_TYPE_NCTL2, + PHY_PATCH_TYPE_ALGXG, + PHY_PATCH_TYPE_ALG1G, + PHY_PATCH_TYPE_NORMAL, + PHY_PATCH_TYPE_DATARAM, + PHY_PATCH_TYPE_RTCT, + PHY_PATCH_TYPE_END +} rtk_phypatch_type_t; + +#define RTK_PATCH_TYPE_FLOW(_id) (PHY_PATCH_TYPE_END + _id) +#define RTK_PATCH_TYPE_FLOWID_MAX PHY_PATCH_TYPE_END +#define RTK_PATCH_SEQ_MAX ( PHY_PATCH_TYPE_END + RTK_PATCH_TYPE_FLOWID_MAX -1) + +typedef struct rtk_hwpatch_s +{ + uint8 patch_op; + uint8 portmask; + uint16 pagemmd; + uint16 addr; + uint8 msb; + uint8 lsb; + uint16 data; + uint8 compare_op; + uint16 sram_p; + uint16 sram_rr; + uint16 sram_rw; + uint16 sram_a; +} rtk_hwpatch_t; + +typedef struct rtk_hwpatch_data_s +{ + rtk_hwpatch_t *conf; + uint32 size; +} rtk_hwpatch_data_t; + +typedef struct rtk_hwpatch_seq_s +{ + uint8 patch_type; + union + { + rtk_hwpatch_data_t data; + uint8 flow_id; + } patch; +} rtk_hwpatch_seq_t; + +typedef struct rt_phy_patch_db_s +{ + /* patch operation */ + int32 (*fPatch_op)(uint32 unit, rtk_port_t port, uint8 portOffset, rtk_hwpatch_t *pPatch_data, uint8 patch_mode); + int32 (*fPatch_flow)(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_flow, uint8 patch_mode); + + /* patch data */ + rtk_hwpatch_seq_t seq_table[RTK_PATCH_SEQ_MAX]; + rtk_hwpatch_seq_t cmp_table[RTK_PATCH_SEQ_MAX]; + +} rt_phy_patch_db_t; +#endif + + + +#endif /* __RTK_PHYLIB_DEF_H */ diff --git a/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/rtk_phylib_rtl826xb.c b/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/rtk_phylib_rtl826xb.c new file mode 100644 index 00000000000..1c33846a70f --- /dev/null +++ b/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/rtk_phylib_rtl826xb.c @@ -0,0 +1,57 @@ +/* + * SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved. + */ + +#include "rtk_phylib_rtl826xb.h" + +/* Indirect Register Access APIs */ +int rtk_phylib_826xb_sds_read(rtk_phydev *phydev, uint32 page, uint32 reg, uint8 msb, uint8 lsb, uint32 *pData) +{ + int32 ret = 0; + uint32 rData = 0; + uint32 op = (page & 0x3f) | ((reg & 0x1f) << 6) | (0x8000); + uint32 i = 0; + uint32 mask = 0; + mask = UINT32_BITS_MASK(msb,lsb); + + RTK_PHYLIB_ERR_CHK(rtk_phylib_mmd_write(phydev, 30, 323, 15, 0, op)); + + for (i = 0; i < 10; i++) + { + RTK_PHYLIB_ERR_CHK(rtk_phylib_mmd_read(phydev, 30, 323, 15, 15, &rData)); + if (rData == 0) + { + break; + } + rtk_phylib_udelay(10); + } + if (i == 10) + { + return -1; + } + + RTK_PHYLIB_ERR_CHK(rtk_phylib_mmd_read(phydev, 30, 322, 15, 0, &rData)); + *pData = REG32_FIELD_GET(rData, lsb, mask); + + return ret; +} + +int rtk_phylib_826xb_sds_write(rtk_phydev *phydev, uint32 page, uint32 reg, uint8 msb, uint8 lsb, uint32 data) +{ + int32 ret = 0; + uint32 wData = 0, rData = 0; + uint32 op = (page & 0x3f) | ((reg & 0x1f) << 6) | (0x8800); + uint32 mask = 0; + mask = UINT32_BITS_MASK(msb,lsb); + + RTK_PHYLIB_ERR_CHK(rtk_phylib_826xb_sds_read(phydev, page, reg, 15, 0, &rData)); + + wData = REG32_FIELD_SET(rData, data, lsb, mask); + + RTK_PHYLIB_ERR_CHK(rtk_phylib_mmd_write(phydev, 30, 321, 15, 0, wData)); + RTK_PHYLIB_ERR_CHK(rtk_phylib_mmd_write(phydev, 30, 323, 15, 0, op)); + + return ret; +} diff --git a/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/rtk_phylib_rtl826xb.h b/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/rtk_phylib_rtl826xb.h new file mode 100644 index 00000000000..9f827d4ba25 --- /dev/null +++ b/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/rtk_phylib_rtl826xb.h @@ -0,0 +1,19 @@ +/* + * SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved. + */ + +#ifndef __RTK_PHYLIB_RTL826XB_H +#define __RTK_PHYLIB_RTL826XB_H + +#if defined(RTK_PHYDRV_IN_LINUX) + #include "rtk_phylib.h" +#else + //#include SDK headers +#endif + +int rtk_phylib_826xb_sds_read(rtk_phydev *phydev, uint32 page, uint32 reg, uint8 msb, uint8 lsb, uint32 *pData); +int rtk_phylib_826xb_sds_write(rtk_phydev *phydev, uint32 page, uint32 reg, uint8 msb, uint8 lsb, uint32 data); + +#endif /* __RTK_PHYLIB_RTL826XB_H */ diff --git a/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/type.h b/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/type.h new file mode 100644 index 00000000000..98d7e15e1e4 --- /dev/null +++ b/target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/type.h @@ -0,0 +1,117 @@ +/* + * SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved. + */ + +#ifndef __COMMON_TYPE_H__ +#define __COMMON_TYPE_H__ + +/* + * Symbol Definition + */ + +#define USING_RTSTK_PKT_AS_RAIL + + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef ETHER_ADDR_LEN +#define ETHER_ADDR_LEN 6 +#endif + +#ifndef IP6_ADDR_LEN +#define IP6_ADDR_LEN 16 +#endif + + +/* + * Data Type Declaration + */ +#ifndef uint64 +typedef unsigned long long uint64; +#endif + +#ifndef int64 +typedef signed long long int64; +#endif + +#ifndef uint32 +typedef unsigned int uint32; +#endif + +#ifndef int32 +typedef signed int int32; +#endif + +#ifndef uint16 +typedef unsigned short uint16; +#endif + +#ifndef int16 +typedef signed short int16; +#endif + +#ifndef uint8 +typedef unsigned char uint8; +#endif + +#ifndef int8 +typedef signed char int8; +#endif + +//#define CONFIG_SDK_WORDSIZE_64 /* not ready */ +#ifdef CONFIG_SDK_WORDSIZE_64 + typedef long int intptr; + typedef unsigned long int uintptr; +#else + typedef int intptr; + typedef unsigned int uintptr; +#endif + + +#ifndef ipaddr_t +typedef uint32 ipaddr_t; /* ipv4 address type */ +#endif + +/* configuration mode type */ +typedef enum rtk_enable_e +{ + DISABLED = 0, + ENABLED, + RTK_ENABLE_END +} rtk_enable_t; + +/* initial state of module */ +typedef enum init_state_e +{ + INIT_NOT_COMPLETED = 0, + INIT_COMPLETED, + INIT_STATE_END +} init_state_t; + +/* ethernet address type */ +typedef struct rtk_mac_s +{ + uint8 octet[ETHER_ADDR_LEN]; +} rtk_mac_t; + +typedef uint32 osal_time_t; +typedef uint32 osal_usecs_t; + +/* + * Macro Definition + */ + +#endif /* __COMMON_TYPE_H__ */ + diff --git a/target/linux/mediatek/filogic/config-6.6 b/target/linux/mediatek/filogic/config-6.6 index 7cf045ade2a..ba472b6ced7 100644 --- a/target/linux/mediatek/filogic/config-6.6 +++ b/target/linux/mediatek/filogic/config-6.6 @@ -428,6 +428,7 @@ CONFIG_RPS=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_MT7622=y CONFIG_RTC_I2C_AND_SPI=y +CONFIG_RTL8261N_PHY=y # CONFIG_RTL8367S_GSW is not set CONFIG_RWSEM_SPIN_ON_OWNER=y CONFIG_SCHED_MC=y diff --git a/target/linux/mediatek/mt7622/config-6.6 b/target/linux/mediatek/mt7622/config-6.6 index 138eb2aaca0..e4a9e4b9cb6 100644 --- a/target/linux/mediatek/mt7622/config-6.6 +++ b/target/linux/mediatek/mt7622/config-6.6 @@ -424,6 +424,7 @@ CONFIG_RPS=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_MT7622=y CONFIG_RTC_I2C_AND_SPI=y +# CONFIG_RTL8261N_PHY is not set CONFIG_RTL8367S_GSW=y CONFIG_RWSEM_SPIN_ON_OWNER=y CONFIG_SCHED_MC=y diff --git a/target/linux/mediatek/mt7623/config-6.6 b/target/linux/mediatek/mt7623/config-6.6 index baa31b465df..d04188f20cd 100644 --- a/target/linux/mediatek/mt7623/config-6.6 +++ b/target/linux/mediatek/mt7623/config-6.6 @@ -541,6 +541,7 @@ CONFIG_RTC_CLASS=y # CONFIG_RTC_DRV_MT7622 is not set CONFIG_RTC_I2C_AND_SPI=y CONFIG_RTC_MC146818_LIB=y +# CONFIG_RTL8261N_PHY is not set # CONFIG_RTL8367S_GSW is not set CONFIG_RWSEM_SPIN_ON_OWNER=y # CONFIG_SERIAL_8250_DMA is not set diff --git a/target/linux/mediatek/mt7629/config-6.6 b/target/linux/mediatek/mt7629/config-6.6 index 5169acb99f0..384311dc710 100644 --- a/target/linux/mediatek/mt7629/config-6.6 +++ b/target/linux/mediatek/mt7629/config-6.6 @@ -301,6 +301,7 @@ CONFIG_REGMAP_MMIO=y CONFIG_RESET_CONTROLLER=y CONFIG_RFS_ACCEL=y CONFIG_RPS=y +# CONFIG_RTL8261N_PHY is not set # CONFIG_RTL8367S_GSW is not set CONFIG_RWSEM_SPIN_ON_OWNER=y CONFIG_SCSI=y diff --git a/target/linux/mediatek/patches-6.6/735-net-phy-realtek-rtl8261n.patch b/target/linux/mediatek/patches-6.6/735-net-phy-realtek-rtl8261n.patch new file mode 100644 index 00000000000..3612b521e1c --- /dev/null +++ b/target/linux/mediatek/patches-6.6/735-net-phy-realtek-rtl8261n.patch @@ -0,0 +1,21 @@ +--- a/drivers/net/phy/Kconfig ++++ b/drivers/net/phy/Kconfig +@@ -334,6 +334,8 @@ config REALTEK_PHY + help + Supports the Realtek 821x PHY. + ++source "drivers/net/phy/rtl8261n/Kconfig" ++ + config RENESAS_PHY + tristate "Renesas PHYs" + help +--- a/drivers/net/phy/Makefile ++++ b/drivers/net/phy/Makefile +@@ -85,6 +85,7 @@ obj-$(CONFIG_ADIN_PHY) += adin.o + obj-y += qcom/ + obj-$(CONFIG_QSEMI_PHY) += qsemi.o + obj-$(CONFIG_REALTEK_PHY) += realtek.o ++obj-y += rtl8261n/ + obj-$(CONFIG_RENESAS_PHY) += uPD60620.o + obj-$(CONFIG_ROCKCHIP_PHY) += rockchip.o + obj-$(CONFIG_SMSC_PHY) += smsc.o From ddfae94a14bf0fc301505da75825dfe473525a33 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Tue, 29 Oct 2024 13:40:11 +0100 Subject: [PATCH 24/27] mediatek: add support for swapping the polarity on usxgmii interfaces This patch comes from the MTK SDK. Signed-off-by: John Crispin --- ...pcs-mtk_usxgmii-add-polarity-control.patch | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 target/linux/mediatek/patches-6.6/736-net-pcs-mtk_usxgmii-add-polarity-control.patch diff --git a/target/linux/mediatek/patches-6.6/736-net-pcs-mtk_usxgmii-add-polarity-control.patch b/target/linux/mediatek/patches-6.6/736-net-pcs-mtk_usxgmii-add-polarity-control.patch new file mode 100644 index 00000000000..678761990b8 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/736-net-pcs-mtk_usxgmii-add-polarity-control.patch @@ -0,0 +1,58 @@ +diff --git a/drivers/net/pcs/pcs-mtk-usxgmii.c b/drivers/net/pcs/pcs-mtk-usxgmii.c +index 9af9035..9caab92 100644 +--- a/drivers/net/pcs/pcs-mtk-usxgmii.c ++++ b/drivers/net/pcs/pcs-mtk-usxgmii.c +@@ -52,6 +52,12 @@ + #define USXGMII_LPA GENMASK(15, 0) + #define USXGMII_LPA_LATCH BIT(31) + ++/* Register to control PCS polarity */ ++#define RG_PHY_TOP_CTRL0 0x82C ++#define USXGMII_PN_SWAP_MASK GENMASK(1, 0) ++#define USXGMII_PN_SWAP_RX BIT(1) ++#define USXGMII_PN_SWAP_TX BIT(0) ++ + /* Register to read PCS link status */ + #define RG_PCS_RX_STATUS0 0x904 + #define RG_PCS_RX_STATUS_UPDATE BIT(16) +@@ -74,6 +80,7 @@ struct mtk_usxgmii_pcs { + struct clk *clk; + struct reset_control *reset; + phy_interface_t interface; ++ unsigned int polarity; + unsigned int neg_mode; + struct list_head node; + }; +@@ -155,6 +162,10 @@ static int mtk_usxgmii_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode + + mtk_usxgmii_reset(mpcs); + ++ /* Configure the interface polarity */ ++ mtk_m32(mpcs, RG_PHY_TOP_CTRL0, ++ USXGMII_PN_SWAP_MASK, mpcs->polarity); ++ + /* Setup USXGMII AN ctrl */ + mtk_m32(mpcs, RG_PCS_AN_CTRL0, + USXGMII_AN_SYNC_CNT | USXGMII_AN_ENABLE, +@@ -332,6 +343,7 @@ static const struct phylink_pcs_ops mtk_usxgmii_pcs_ops = { + static int mtk_usxgmii_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; ++ struct device_node *np = dev->of_node; + struct mtk_usxgmii_pcs *mpcs; + + mpcs = devm_kzalloc(dev, sizeof(*mpcs), GFP_KERNEL); +@@ -342,6 +354,13 @@ static int mtk_usxgmii_probe(struct platform_device *pdev) + if (IS_ERR(mpcs->base)) + return PTR_ERR(mpcs->base); + ++ if (of_property_read_bool(np->parent, "mediatek,pnswap")) ++ mpcs->polarity = USXGMII_PN_SWAP_TX | USXGMII_PN_SWAP_RX; ++ else if (of_property_read_bool(np, "mediatek,pnswap-tx")) ++ mpcs->polarity = USXGMII_PN_SWAP_TX; ++ else if (of_property_read_bool(np, "mediatek,pnswap-rx")) ++ mpcs->polarity = USXGMII_PN_SWAP_RX; ++ + mpcs->dev = dev; + mpcs->pcs.ops = &mtk_usxgmii_pcs_ops; + mpcs->pcs.poll = true; From a85f11f191933b0c947428a0d45be484156127eb Mon Sep 17 00:00:00 2001 From: John Crispin Date: Sat, 21 Sep 2024 09:48:47 +0200 Subject: [PATCH 25/27] mediatek: filogic: add Arcadyan Mozart platform * Mediatek MT7988A (4x Cortex-A73, up to 1.8 GHz clock speed) * 8 GiB eMMC * 4 GiB DDR4 RAM * 2x 10000M + 1x 1000M ports * MT7996 Tri-band (2.4G, 5G, 6G) 4T4R 802.11be Wi-Fi * 2 buttons (Reset, WPS) * 2x LED for each GMAC * USB-C PD power input Signed-off-by: John Crispin --- .../mediatek/dts/mt7988a-arcadyan-mozart.dts | 336 ++++++++++++++++++ .../filogic/base-files/etc/board.d/02_network | 3 + .../base-files/lib/upgrade/platform.sh | 2 + target/linux/mediatek/image/filogic.mk | 24 ++ 4 files changed, 365 insertions(+) create mode 100644 target/linux/mediatek/dts/mt7988a-arcadyan-mozart.dts diff --git a/target/linux/mediatek/dts/mt7988a-arcadyan-mozart.dts b/target/linux/mediatek/dts/mt7988a-arcadyan-mozart.dts new file mode 100644 index 00000000000..8b5f0526b20 --- /dev/null +++ b/target/linux/mediatek/dts/mt7988a-arcadyan-mozart.dts @@ -0,0 +1,336 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) + +/dts-v1/; +#include "mt7988a-rfb.dts" +#include +#include +#include + +/ { + compatible = "arcadyan,mozart", "mediatek,mt7988a"; + model = "MediaTek / Arcadyan - Mozart"; + + aliases { + serial0 = &uart0; + led-boot = &led_status_blue; + led-failsafe = &led_status_red; + led-running = &led_status_green; + led-upgrade = &led_status_green; + }; + + chosen { + rootdisk = <&emmc_rootfs>; + }; + + gpio-leds { + compatible = "gpio-leds"; + + wifi_white { + color = ; + function = LED_FUNCTION_STATUS; + gpios = <&pio 68 GPIO_ACTIVE_HIGH>; + }; + + led_status_red: wifi_red { + color = ; + function = LED_FUNCTION_STATUS; + gpios = <&pio 29 GPIO_ACTIVE_HIGH>; + }; + + led_status_green: wifi_green { + color = ; + function = LED_FUNCTION_STATUS; + gpios = <&pio 30 GPIO_ACTIVE_HIGH>; + }; + + led_status_blue: wifi_blue { + color = ; + function = LED_FUNCTION_STATUS; + gpios = <&pio 31 GPIO_ACTIVE_HIGH>; + }; + }; + + keys { + compatible = "gpio-keys"; + + button-reset { + label = "reset"; + linux,code = ; + gpios = <&pio 13 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&pio { + mdio0_pins: mdio0-pins { + mux { + function = "eth"; + groups = "mdc_mdio0"; + }; + + conf { + groups = "mdc_mdio0"; + drive-strength = ; + }; + }; + + spic_pins: spi1-pins { + mux { + function = "spi"; + groups = "spi1"; + }; + }; +}; + +&usxgmiisys0 { + mediatek,pnswap-rx; +}; + +&usxgmiisys1 { + mediatek,pnswap-rx; +}; + +&mdio_bus { + #address-cells = <1>; + #size-cells = <0>; + reset-gpios = <&pio 72 GPIO_ACTIVE_LOW>; + reset-assert-us = <100000>; + reset-deassert-us = <100000>; + + phy0: ethernet-phy@0 { + reg = <0>; + compatible = "ethernet-phy-ieee802.3-c45"; + }; + + phy8: ethernet-phy@8 { + reg = <8>; + compatible = "ethernet-phy-ieee802.3-c45"; + }; +}; + +&gmac0 { + nvmem-cells = <&macaddr_factory_4 3>; + nvmem-cell-names = "mac-address"; +}; + +&gmac1 { + phy-mode = "usxgmii"; + phy-connection-type = "usxgmii"; + phy = <&phy0>; + nvmem-cells = <&macaddr_factory_4 4>; + nvmem-cell-names = "mac-address"; + status = "okay"; +}; + +&gmac2 { + phy-mode = "usxgmii"; + phy-connection-type = "usxgmii"; + phy = <&phy8>; + nvmem-cells = <&macaddr_factory_4 5>; + nvmem-cell-names = "mac-address"; + status = "okay"; +}; + +&switch { + /delete-node/ports; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + gsw_port0: port@0 { + reg = <0>; + label = "lan0"; + phy-mode = "internal"; + phy-handle = <&gsw_phy0>; + }; + + port@6 { + reg = <6>; + ethernet = <&gmac0>; + phy-mode = "internal"; + + fixed-link { + speed = <10000>; + full-duplex; + pause; + }; + }; + }; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; + clock-frequency = <100000>; + status = "okay"; + + icp201xx@63{ + compatible = "invensense,icp201xx"; + reg = <0x63>; + #address-cells = <1>; + #size-cells = <0>; + }; +}; + +&uart1 { + status = "okay"; +}; + +&fan { + pwms = <&pwm 1 40000 0>; + status = "okay"; +}; + +&pwm { + status = "okay"; +}; + +&spi1 { + pinctrl-names = "default"; + /* pin shared with snfi */ + pinctrl-0 = <&spic_pins>; + status = "disabled"; +}; + +&mmc0 { + pinctrl-names = "default", "state_uhs"; + pinctrl-0 = <&mmc0_pins_emmc_51>; + pinctrl-1 = <&mmc0_pins_emmc_51>; + bus-width = <8>; + max-frequency = <200000000>; + cap-mmc-highspeed; + mmc-hs200-1_8v; + mmc-hs400-1_8v; + hs400-ds-delay = <0x12814>; + vqmmc-supply = <®_1p8v>; + vmmc-supply = <®_3p3v>; + non-removable; + no-sd; + no-sdio; + status = "okay"; + + card@0 { + compatible = "mmc-card"; + reg = <0>; + + block { + compatible = "block-device"; + partitions { + block-partition-env { + partname = "u-boot-env"; + nvmem-layout { + compatible = "u-boot,env-layout"; + }; + }; + + emmc_rootfs: block-partition-production { + partname = "production"; + }; + + block-partition-factory { + partname = "factory"; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + eeprom_factory_0: eeprom@0 { + reg = <0x0 0x1e00>; + }; + + macaddr_factory_4: macaddr@a { + compatible = "mac-base"; + reg = <0x4 0x6>; + #nvmem-cell-cells = <1>; + }; + }; + }; + }; + }; + }; +}; + +&cpu_thermal { + /delete-node/cooling-maps; + /delete-node/trips; + + trips { + cpu_trip_crit: crit { + temperature = <125000>; + hysteresis = <2000>; + type = "critical"; + }; + + cpu_trip_hot: hot { + temperature = <120000>; + hysteresis = <2000>; + type = "hot"; + }; + + cpu_trip_active_high: active-high { + temperature = <110000>; + hysteresis = <2000>; + type = "active"; + }; + + cpu_trip_active_med: active-med { + temperature = <80000>; + hysteresis = <2000>; + type = "active"; + }; + + cpu_trip_active_low: active-low { + temperature = <60000>; + hysteresis = <2000>; + type = "active"; + }; + + cpu_trip_active_silent: active-silent { + temperature = <40000>; + hysteresis = <2000>; + type = "active"; + }; + }; + + cooling-maps { + cpu-active-high { + /* active: set fan to cooling level 3 */ + cooling-device = <&fan 3 3>; + trip = <&cpu_trip_active_high>; + }; + + cpu-active-med { + /* active: set fan to cooling level 2 */ + cooling-device = <&fan 2 2>; + trip = <&cpu_trip_active_med>; + }; + + cpu-active-low { + /* active: set fan to cooling level 1 */ + cooling-device = <&fan 1 1>; + trip = <&cpu_trip_active_low>; + }; + + cpu-active-silent { + /* active: set fan to cooling level 0 */ + cooling-device = <&fan 0 0>; + trip = <&cpu_trip_active_silent>; + }; + }; +}; + +&pcie0 { + status = "okay"; + + pcie@0,0 { + reg = <0x0000 0 0 0 0>; + + mt7996@1,0 { + reg = <0x0000 0 0 0 0>; + nvmem-cells = <&eeprom_factory_0>; + nvmem-cell-names = "eeprom"; + }; + }; +}; diff --git a/target/linux/mediatek/filogic/base-files/etc/board.d/02_network b/target/linux/mediatek/filogic/base-files/etc/board.d/02_network index af5c4ceafee..fff39006da8 100644 --- a/target/linux/mediatek/filogic/base-files/etc/board.d/02_network +++ b/target/linux/mediatek/filogic/base-files/etc/board.d/02_network @@ -21,6 +21,9 @@ mediatek_setup_interfaces() acer,predator-w6) ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 game" eth1 ;; + arcadyan,mozart) + ucidef_set_interfaces_lan_wan "lan0 eth1" eth2 + ;; asus,rt-ax59u|\ cetron,ct3003|\ confiabits,mt7981|\ diff --git a/target/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh b/target/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh index edc04565663..7fe2d29d31d 100755 --- a/target/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh +++ b/target/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh @@ -90,6 +90,7 @@ platform_do_upgrade() { fit_do_upgrade "$1" ;; acer,predator-w6|\ + arcadyan,mozart|\ smartrg,sdg-8612|\ smartrg,sdg-8614|\ smartrg,sdg-8622|\ @@ -202,6 +203,7 @@ platform_copy_config() { fi ;; acer,predator-w6|\ + arcadyan,mozart|\ glinet,gl-mt2500|\ glinet,gl-mt6000|\ glinet,gl-x3000|\ diff --git a/target/linux/mediatek/image/filogic.mk b/target/linux/mediatek/image/filogic.mk index 37fe740c31d..5dfde755a01 100644 --- a/target/linux/mediatek/image/filogic.mk +++ b/target/linux/mediatek/image/filogic.mk @@ -254,6 +254,30 @@ define Device/asus_tuf-ax4200 endef TARGET_DEVICES += asus_tuf-ax4200 +define Device/arcadyan_mozart + DEVICE_VENDOR := Arcadyan + DEVICE_MODEL := Mozart + DEVICE_DTS := mt7988a-arcadyan-mozart + DEVICE_DTS_DIR := ../dts + DEVICE_DTC_FLAGS := --pad 4096 + DEVICE_DTS_LOADADDR := 0x45f00000 + DEVICE_PACKAGES := kmod-hwmon-pwmfan e2fsprogs f2fsck mkf2fs kmod-mt7996-firmware + KERNEL_LOADADDR := 0x46000000 + KERNEL := kernel-bin | gzip + KERNEL_INITRAMFS := kernel-bin | lzma | \ + fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb with-initrd | pad-to 64k + KERNEL_INITRAMFS_SUFFIX := .itb + IMAGE_SIZE := $$(shell expr 64 + $$(CONFIG_TARGET_ROOTFS_PARTSIZE))m + IMAGES := sysupgrade.itb + IMAGE/sysupgrade.itb := append-kernel | fit gzip $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb external-with-rootfs | pad-rootfs | append-metadata + ARTIFACTS := emmc-preloader.bin emmc-bl31-uboot.fip emmc-gpt.bin + ARTIFACT/emmc-gpt.bin := mt798x-gpt emmc + ARTIFACT/emmc-preloader.bin := mt7988-bl2 emmc-comb + ARTIFACT/emmc-bl31-uboot.fip := mt7988-bl31-uboot arcadyan_mozart + SUPPORTED_DEVICES += arcadyan,mozart +endef +TARGET_DEVICES += arcadyan_mozart + define Device/asus_tuf-ax6000 DEVICE_VENDOR := ASUS DEVICE_MODEL := TUF-AX6000 From 2915cfb626367208ada0c91e27529f9516ce1873 Mon Sep 17 00:00:00 2001 From: Paul Donald Date: Tue, 29 Oct 2024 21:49:00 +0100 Subject: [PATCH 26/27] kernel: KERNEL_NET_L3_MASTER_DEV default to y if !SMALL_FLASH Follow-up for 45d541bb409355f090b971d96ebebd8610ef84a7 This change allows features such as kmod-vrf ``` KERNEL_NET_L3_MASTER_DEV=n x86_64 generic bzImage 6,927,360 bytes aarch64 coretex-a53 kernel 4,268,836 bytes KERNEL_NET_L3_MASTER_DEV=y x86_64 generic bzImage 6,931,456 bytes aarch64 coretex-a53 kernel 4,273,042 bytes Delta: x86_64 generic +4096 bytes aarch64 coretex-a53 +4206 bytes x86_64 generic vrf.ko - 258,792 bytes aarch64 coretex-a53 vrf.ko - 263,632 bytes ``` See: https://forum.openwrt.org/t/vrf-support-testing-out-evpn-at-home/181108 https://forum.openwrt.org/t/please-enable-net-l3-master-dev-in-kernel-build-by-default/201825 Signed-off-by: Paul Donald Link: https://github.com/openwrt/openwrt/pull/16819 Signed-off-by: Robert Marko --- config/Config-kernel.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/Config-kernel.in b/config/Config-kernel.in index 43ed9eaf36b..0fa039db404 100644 --- a/config/Config-kernel.in +++ b/config/Config-kernel.in @@ -1187,9 +1187,11 @@ endif config KERNEL_NET_L3_MASTER_DEV bool "L3 Master device support" + default y if !SMALL_FLASH help This module provides glue between core networking code and device drivers to support L3 master devices like VRF. + Increases the compressed kernel size by ~4kB (as of Linux 6.6). config KERNEL_XDP_SOCKETS bool "XDP sockets support" From efd1ec51a149cfa536b5e37a5a5d1a8b9fe363ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Fri, 1 Nov 2024 21:44:43 +0100 Subject: [PATCH 27/27] bcm27xx-gpu-fw: fix package MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Install definition was accidentally removed in 7afdbc0955a5 and IB fails. Fixes: 7afdbc0955a5 ("bcm27xx-gpu-fw: update to latest version") Signed-off-by: Álvaro Fernández Rojas --- package/kernel/bcm27xx-gpu-fw/Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/package/kernel/bcm27xx-gpu-fw/Makefile b/package/kernel/bcm27xx-gpu-fw/Makefile index 6de2fd7501c..0b8f5781e54 100644 --- a/package/kernel/bcm27xx-gpu-fw/Makefile +++ b/package/kernel/bcm27xx-gpu-fw/Makefile @@ -4,7 +4,7 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=bcm27xx-gpu-fw PKG_VERSION:=2024.10.08 PKG_VERSION_REAL:=1.$(subst .,,$(PKG_VERSION)) -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_SOURCE:=raspi-firmware_$(PKG_VERSION_REAL).orig.tar.xz PKG_SOURCE_URL:=https://github.com/raspberrypi/firmware/releases/download/$(PKG_VERSION_REAL) @@ -33,6 +33,10 @@ define Build/Compile true endef +define Package/bcm27xx-gpu-fw/install + true +endef + define Build/InstallDev $(CP) $(PKG_BUILD_DIR)/boot/bootcode.bin $(KERNEL_BUILD_DIR) $(CP) $(PKG_BUILD_DIR)/boot/LICENCE.broadcom $(KERNEL_BUILD_DIR)